@planet-matrix/mobius-model 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +4 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +18 -3
- package/package.json +3 -3
- package/scripts/build.ts +4 -4
- package/src/basic/README.md +143 -0
- package/src/basic/array.ts +872 -0
- package/src/basic/bigint.ts +114 -0
- package/src/basic/boolean.ts +180 -0
- package/src/basic/error.ts +51 -0
- package/src/basic/function.ts +453 -0
- package/src/basic/helper.ts +276 -0
- package/src/basic/index.ts +15 -0
- package/src/basic/is.ts +320 -0
- package/src/basic/number.ts +178 -0
- package/src/basic/object.ts +58 -0
- package/src/basic/promise.ts +464 -0
- package/src/basic/regexp.ts +7 -0
- package/src/basic/stream.ts +140 -0
- package/src/basic/string.ts +308 -0
- package/src/basic/symbol.ts +164 -0
- package/src/basic/temporal.ts +224 -0
- package/src/index.ts +2 -0
- package/src/type/README.md +330 -0
- package/src/type/array.ts +5 -0
- package/src/type/boolean.ts +471 -0
- package/src/type/class.ts +419 -0
- package/src/type/function.ts +1519 -0
- package/src/type/helper.ts +135 -0
- package/src/type/index.ts +14 -0
- package/src/type/intersection.ts +93 -0
- package/src/type/is.ts +247 -0
- package/src/type/iteration.ts +233 -0
- package/src/type/number.ts +732 -0
- package/src/type/object.ts +788 -0
- package/src/type/path.ts +73 -0
- package/src/type/string.ts +1004 -0
- package/src/type/tuple.ts +2424 -0
- package/src/type/union.ts +108 -0
- package/tests/unit/basic/array.spec.ts +290 -0
- package/tests/unit/basic/bigint.spec.ts +50 -0
- package/tests/unit/basic/boolean.spec.ts +74 -0
- package/tests/unit/basic/error.spec.ts +32 -0
- package/tests/unit/basic/function.spec.ts +175 -0
- package/tests/unit/basic/helper.spec.ts +118 -0
- package/tests/unit/basic/number.spec.ts +74 -0
- package/tests/unit/basic/object.spec.ts +15 -0
- package/tests/unit/basic/promise.spec.ts +232 -0
- package/tests/unit/basic/regexp.spec.ts +11 -0
- package/tests/unit/basic/stream.spec.ts +120 -0
- package/tests/unit/basic/string.spec.ts +74 -0
- package/tests/unit/basic/symbol.spec.ts +72 -0
- package/tests/unit/basic/temporal.spec.ts +78 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/reactor/index.d.ts +0 -3
- package/dist/reactor/index.d.ts.map +0 -1
- package/dist/reactor/reactor-core/flags.d.ts +0 -99
- package/dist/reactor/reactor-core/flags.d.ts.map +0 -1
- package/dist/reactor/reactor-core/index.d.ts +0 -4
- package/dist/reactor/reactor-core/index.d.ts.map +0 -1
- package/dist/reactor/reactor-core/primitive.d.ts +0 -276
- package/dist/reactor/reactor-core/primitive.d.ts.map +0 -1
- package/dist/reactor/reactor-core/reactive-system.d.ts +0 -241
- package/dist/reactor/reactor-core/reactive-system.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/branch.d.ts +0 -19
- package/dist/reactor/reactor-operators/branch.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/convert.d.ts +0 -30
- package/dist/reactor/reactor-operators/convert.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/create.d.ts +0 -26
- package/dist/reactor/reactor-operators/create.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/filter.d.ts +0 -269
- package/dist/reactor/reactor-operators/filter.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/index.d.ts +0 -8
- package/dist/reactor/reactor-operators/index.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/join.d.ts +0 -48
- package/dist/reactor/reactor-operators/join.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/map.d.ts +0 -165
- package/dist/reactor/reactor-operators/map.d.ts.map +0 -1
- package/dist/reactor/reactor-operators/utility.d.ts +0 -48
- package/dist/reactor/reactor-operators/utility.d.ts.map +0 -1
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
|
|
2
|
+
import { isAnyFunction, isFunction } from "./is.ts"
|
|
3
|
+
|
|
4
|
+
import { booleanFrom } from "./boolean.ts"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Return the input value as is, ignoring any additional arguments.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```
|
|
11
|
+
* // Expect: 5
|
|
12
|
+
* const example1 = asIs(5)
|
|
13
|
+
* // Expect: "hello"
|
|
14
|
+
* const example2 = asIs("hello", 1, 2, 3)
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export const asIs = <T = unknown>(target: T, ..._args: unknown[]): T => target
|
|
18
|
+
/**
|
|
19
|
+
* Return undefined, ignoring any input arguments.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```
|
|
23
|
+
* // Expect: undefined
|
|
24
|
+
* const example1 = asUndefined()
|
|
25
|
+
* // Expect: undefined
|
|
26
|
+
* const example2 = asUndefined(1, "hello", null)
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export const asUndefined = (..._target: unknown[]): undefined => undefined
|
|
30
|
+
/**
|
|
31
|
+
* Return null, ignoring any input arguments.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```
|
|
35
|
+
* // Expect: null
|
|
36
|
+
* const example1 = asNull()
|
|
37
|
+
* // Expect: null
|
|
38
|
+
* const example2 = asNull(1, "hello", undefined)
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export const asNull = (..._target: unknown[]): null => null
|
|
42
|
+
/**
|
|
43
|
+
* Return void, ignoring any input arguments.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```
|
|
47
|
+
* // Expect: void
|
|
48
|
+
* const example1 = asVoid()
|
|
49
|
+
* // Expect: void
|
|
50
|
+
* const example2 = asVoid(1, "hello", null)
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export const asVoid = (..._target: unknown[]): void => { /* do nothing */ }
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check whether two values are strictly equal using `===`.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```
|
|
60
|
+
* // Expect: true
|
|
61
|
+
* const example1 = isStrictEqual(1, 1)
|
|
62
|
+
* // Expect: false
|
|
63
|
+
* const example2 = isStrictEqual(1, "1")
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness}
|
|
67
|
+
*/
|
|
68
|
+
export const isStrictEqual = (v1: unknown, v2: unknown): boolean => v1 === v2
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Check whether two values are loosely equal using `==`.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```
|
|
75
|
+
* // Expect: true
|
|
76
|
+
* const example1 = isLooseEqual(1, "1")
|
|
77
|
+
* // Expect: false
|
|
78
|
+
* const example2 = isLooseEqual(0, "1")
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness}
|
|
82
|
+
*/
|
|
83
|
+
// eslint-disable-next-line eqeqeq
|
|
84
|
+
export const isLooseEqual = (v1: unknown, v2: unknown): boolean => v1 == v2
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Check whether two values are equal using `Object.is`.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```
|
|
91
|
+
* // Expect: true
|
|
92
|
+
* const example1 = isObjectEqual(NaN, NaN)
|
|
93
|
+
* // Expect: false
|
|
94
|
+
* const example2 = isObjectEqual(0, -0)
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness}
|
|
98
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is}
|
|
99
|
+
*/
|
|
100
|
+
export const isObjectEqual = (v1: unknown, v2: unknown): boolean => Object.is(v1, v2)
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Invoke the conditional function with the target value, according to the predicate result.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```
|
|
107
|
+
* const example1 = ifElse(true, () => "yes", () => "no")
|
|
108
|
+
* // Expect: "yes"
|
|
109
|
+
* const example2 = ifElse(false, () => "yes", () => "no")
|
|
110
|
+
* // Expect: "no"
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export const ifElse = <X = unknown, TR = unknown, ER = unknown>(
|
|
114
|
+
pred: unknown,
|
|
115
|
+
thenFn: (x?: X) => TR,
|
|
116
|
+
elseFn: (x?: X) => ER,
|
|
117
|
+
x?: X,
|
|
118
|
+
): TR | ER => {
|
|
119
|
+
return booleanFrom(isAnyFunction(pred) ? pred(x) : pred) ? thenFn(x) : elseFn(x)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Invoke a function when the predicate result is truthy.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```
|
|
127
|
+
* // Expect: 4
|
|
128
|
+
* const example1 = when(true, (value?: number) => (value ?? 0) + 1, 3)
|
|
129
|
+
* // Expect: 3
|
|
130
|
+
* const example2 = when(false, (value?: number) => (value ?? 0) + 1, 3)
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
export function when<X = unknown, WR = unknown>(pred: unknown, whenFn: (x?: X) => WR): WR
|
|
134
|
+
export function when<X = unknown, WR = unknown>(pred: unknown, whenFn: (x?: X) => WR, x: X): WR | X
|
|
135
|
+
export function when<X = unknown, WR = unknown>(pred: unknown, whenFn: (x?: X) => WR, x?: X): WR | X | undefined {
|
|
136
|
+
return booleanFrom(isAnyFunction(pred) ? pred(x) : pred) ? whenFn(x) : x
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Invoke a function when the predicate result is falsy.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```
|
|
144
|
+
* // Expect: 2
|
|
145
|
+
* const example1 = unless(false, (value?: number) => (value ?? 0) + 1, 1)
|
|
146
|
+
* // Expect: 1
|
|
147
|
+
* const example2 = unless(true, (value?: number) => (value ?? 0) + 1, 1)
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
export function unless<X = unknown, UR = unknown>(pred: unknown, unlessFn: (x?: X) => UR): UR
|
|
151
|
+
export function unless<X = unknown, UR = unknown>(pred: unknown, unlessFn: (x?: X) => UR, x: X): UR
|
|
152
|
+
export function unless<X = unknown, UR = unknown>(
|
|
153
|
+
pred: unknown,
|
|
154
|
+
unlessFn: (x?: X) => UR,
|
|
155
|
+
x?: X,
|
|
156
|
+
): UR | X | undefined {
|
|
157
|
+
return !booleanFrom(isAnyFunction(pred) ? pred(x) : pred) ? unlessFn(x) : x
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Evaluate an immediate if expression.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```
|
|
165
|
+
* // Expect: "yes"
|
|
166
|
+
* const example1 = iif(true, "yes", "no")
|
|
167
|
+
* // Expect: "no"
|
|
168
|
+
* const example2 = iif(false, "yes", "no")
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* @see {@link booleanFrom}
|
|
172
|
+
*/
|
|
173
|
+
export const iif = <X = unknown, Y = unknown>(cond: unknown, trueValue: X, falseValue: Y): X | Y => {
|
|
174
|
+
return booleanFrom(isAnyFunction(cond) ? cond(trueValue) : cond) ? trueValue : falseValue
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export type GuardCondition<V> = [judgement: boolean, value: V]
|
|
178
|
+
/**
|
|
179
|
+
* Pick the first matching value from guard conditions.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```
|
|
183
|
+
* // Expect: "b"
|
|
184
|
+
* const example1 = guards([
|
|
185
|
+
* [false, "a"],
|
|
186
|
+
* [true, "b"],
|
|
187
|
+
* ], "z")
|
|
188
|
+
* // Expect: "z"
|
|
189
|
+
* const example2 = guards([[false, "a"]], "z")
|
|
190
|
+
* ```
|
|
191
|
+
*
|
|
192
|
+
* @see {@link https://hackage.haskell.org/package/Boolean-0.2.4/candidate/docs/Data-Boolean.html}
|
|
193
|
+
* @see {@link https://hackage.haskell.org/package/Boolean-0.2.4/candidate/docs/src/Data-Boolean.html#guardedB}
|
|
194
|
+
*/
|
|
195
|
+
export const guards = <V = unknown>(conditions: Array<GuardCondition<V>>, defaultValue: V): V => {
|
|
196
|
+
for (const [judgement, value] of conditions) {
|
|
197
|
+
if (judgement) { return value }
|
|
198
|
+
}
|
|
199
|
+
return defaultValue
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export type CaseCondition<P, V> = [predicate: (predicated?: P) => boolean, value: V]
|
|
203
|
+
/**
|
|
204
|
+
* Pick the first matching value from predicate cases.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```
|
|
208
|
+
* // Expect: "mid"
|
|
209
|
+
* const example1 = cases(3, [
|
|
210
|
+
* [(value?: number) => (value ?? 0) > 5, "big"],
|
|
211
|
+
* [(value?: number) => (value ?? 0) > 1, "mid"],
|
|
212
|
+
* ], "small")
|
|
213
|
+
* // Expect: "small"
|
|
214
|
+
* const example2 = cases(0, [[(value?: number) => (value ?? 0) > 1, "mid"]], "small")
|
|
215
|
+
* ```
|
|
216
|
+
*
|
|
217
|
+
* @see {@link https://hackage.haskell.org/package/Boolean-0.2.4/candidate/docs/src/Data-Boolean.html#caseB}
|
|
218
|
+
*/
|
|
219
|
+
export const cases = <P = unknown, V = unknown>(
|
|
220
|
+
predicated: P,
|
|
221
|
+
conditions: Array<CaseCondition<P, V>>,
|
|
222
|
+
defaultValue: V,
|
|
223
|
+
): V => {
|
|
224
|
+
for (const [predicate, value] of conditions) {
|
|
225
|
+
if (predicate(predicated)) {
|
|
226
|
+
return value
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return defaultValue
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export interface TryCatch {
|
|
233
|
+
<Target>(tryer: () => Target, catcher: (exception: unknown) => Target): Target
|
|
234
|
+
<Target>(tryer: () => Target, catchallValue: Target): Target
|
|
235
|
+
/**
|
|
236
|
+
* 未提供 `catcher` 或 `catchallValue` 的情况下,若 `tryer` 抛出异常,则返回 `undefined`
|
|
237
|
+
*/
|
|
238
|
+
<Target>(tryer: () => Target): Target | undefined
|
|
239
|
+
(tryer: () => void): void
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Execute a function and catch any exception, returning either a catch value or undefined.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```
|
|
246
|
+
* // Expect: "ok"
|
|
247
|
+
* const example1 = tryCatch(() => "ok", () => "error")
|
|
248
|
+
* // Expect: "error"
|
|
249
|
+
* const example2 = tryCatch(() => { throw new Error("fail") }, () => "error")
|
|
250
|
+
* // Expect: 0
|
|
251
|
+
* const example3 = tryCatch(() => { throw new Error("fail") }, 0)
|
|
252
|
+
* // Expect: undefined
|
|
253
|
+
* const example4 = tryCatch(() => { throw new Error("fail") })
|
|
254
|
+
*/
|
|
255
|
+
export const tryCatch: TryCatch = <Target>(
|
|
256
|
+
tryer: () => Target,
|
|
257
|
+
catcherOrCatchallValue?: Target | ((exception: unknown) => Target),
|
|
258
|
+
): Target | undefined => {
|
|
259
|
+
try {
|
|
260
|
+
return tryer()
|
|
261
|
+
}
|
|
262
|
+
catch (exception) {
|
|
263
|
+
// NOTE: intended redundant type guard
|
|
264
|
+
if (catcherOrCatchallValue !== undefined) {
|
|
265
|
+
if (isFunction(catcherOrCatchallValue)) {
|
|
266
|
+
return catcherOrCatchallValue(exception)
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
return catcherOrCatchallValue
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
return undefined
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from "./helper.ts"
|
|
2
|
+
export * from "./is.ts"
|
|
3
|
+
export * from "./string.ts"
|
|
4
|
+
export * from "./number.ts"
|
|
5
|
+
export * from "./boolean.ts"
|
|
6
|
+
export * from "./bigint.ts"
|
|
7
|
+
export * from "./symbol.ts"
|
|
8
|
+
export * from "./array.ts"
|
|
9
|
+
export * from "./object.ts"
|
|
10
|
+
export * from "./function.ts"
|
|
11
|
+
export * from "./temporal.ts"
|
|
12
|
+
export * from "./error.ts"
|
|
13
|
+
export * from "./regexp.ts"
|
|
14
|
+
export * from "./promise.ts"
|
|
15
|
+
export * from "./stream.ts"
|
package/src/basic/is.ts
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
// oxlint-disable no-explicit-any ban-types
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
AnyAsyncFunction,
|
|
5
|
+
AnyAsyncGeneratorFunction,
|
|
6
|
+
AnyFunction,
|
|
7
|
+
AnyGeneratorFunction,
|
|
8
|
+
AnySyncFunction,
|
|
9
|
+
NonPrimitive,
|
|
10
|
+
PlainObject,
|
|
11
|
+
Primitive
|
|
12
|
+
} from "#Source/type/index.ts"
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 进行类型检测的常用手段包括:
|
|
16
|
+
* - typeof: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof
|
|
17
|
+
* https://tc39.es/ecma262/#sec-typeof-operator
|
|
18
|
+
* - instanceof: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof
|
|
19
|
+
* - toString: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
|
|
20
|
+
*
|
|
21
|
+
* - `typeof` operator can operate on non-exist variable.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
27
|
+
export const isPrimitive = (target: unknown): target is Primitive => {
|
|
28
|
+
return isString(target) || isNumber(target) || isBoolean(target) || isBigInt(target) || isSymbol(target) || isNull(target) || isUndefined(target)
|
|
29
|
+
}
|
|
30
|
+
export const isNonPrimitive = (target: unknown): target is NonPrimitive => {
|
|
31
|
+
return isPrimitive(target) === false
|
|
32
|
+
}
|
|
33
|
+
export const isString = (target: unknown): target is string => {
|
|
34
|
+
return Object.prototype.toString.call(target) === "[object String]"
|
|
35
|
+
}
|
|
36
|
+
export const isNumber = (target: unknown): target is number => {
|
|
37
|
+
return Object.prototype.toString.call(target) === "[object Number]" && isNaN(Number.parseFloat(String(target)))
|
|
38
|
+
}
|
|
39
|
+
export const isNaN = (target: unknown): boolean => {
|
|
40
|
+
return Number.isNaN(target)
|
|
41
|
+
}
|
|
42
|
+
export const isFiniteNumber = (target: unknown): target is number => {
|
|
43
|
+
return isNumber(target) && Number.isFinite(target)
|
|
44
|
+
}
|
|
45
|
+
export const isInfiniteNumber = (target: unknown): target is number => {
|
|
46
|
+
return isNumber(target) && !Number.isFinite(target)
|
|
47
|
+
}
|
|
48
|
+
export const isBoolean = (target: unknown): target is boolean => {
|
|
49
|
+
return Object.prototype.toString.call(target) === "[object Boolean]"
|
|
50
|
+
}
|
|
51
|
+
export const isTrue = (target: unknown): target is true => {
|
|
52
|
+
return isBoolean(target) && target === true
|
|
53
|
+
}
|
|
54
|
+
export const isFalse = (target: unknown): target is false => {
|
|
55
|
+
return isBoolean(target) && target === false
|
|
56
|
+
}
|
|
57
|
+
export const isBigInt = (target: unknown): target is bigint => {
|
|
58
|
+
return Object.prototype.toString.call(target) === "[object BigInt]"
|
|
59
|
+
}
|
|
60
|
+
export const isSymbol = (target: unknown): target is symbol => {
|
|
61
|
+
return Object.prototype.toString.call(target) === "[object Symbol]"
|
|
62
|
+
}
|
|
63
|
+
export const isNull = (target: unknown): target is null => {
|
|
64
|
+
return Object.prototype.toString.call((target)) === "[object Null]"
|
|
65
|
+
}
|
|
66
|
+
export const isUndefined = (target: unknown): target is undefined => {
|
|
67
|
+
return Object.prototype.toString.call(target) === "[object Undefined]"
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* @see {@link https://stackoverflow.com/a/52097700}
|
|
71
|
+
*/
|
|
72
|
+
export const isDefined = <T>(target: T | undefined): target is T => {
|
|
73
|
+
return isUndefined(target) === false
|
|
74
|
+
}
|
|
75
|
+
export const isNil = (target: unknown): target is (null | undefined) => {
|
|
76
|
+
return target === null || target === undefined
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Predicate whether the target is an Object, use `instanceof` operator to check.
|
|
81
|
+
*
|
|
82
|
+
* @see {@link isGeneralObject}, {@link isPlainObject}
|
|
83
|
+
*/
|
|
84
|
+
// oxlint-disable-next-line no-wrapper-object-types
|
|
85
|
+
export const isObject = (target: unknown): target is Object => {
|
|
86
|
+
// oxlint-disable-next-line no-instanceof-builtins
|
|
87
|
+
return target instanceof Object
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Predicate whether the target is a general object, use `typeof` operator to check.
|
|
91
|
+
*
|
|
92
|
+
* A general object is an object that is:
|
|
93
|
+
* - not `null`, not a `function`, not a `primitive`.
|
|
94
|
+
*
|
|
95
|
+
* Any other object is a general object:
|
|
96
|
+
* - `Array` instance, `Map` instance, `WeakMap` instance, `Set` instance, `Date` instance, etc.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```
|
|
100
|
+
* typeof null // => 'object'
|
|
101
|
+
* typeof [] // => 'object'
|
|
102
|
+
* typeof {} // => 'object'
|
|
103
|
+
* typeof { a: 1 } // => 'object'
|
|
104
|
+
* typeof (new Map()) // => 'object'
|
|
105
|
+
* typeof (new WeakMap()) // => 'object'
|
|
106
|
+
* typeof (new Set()) // => 'object'
|
|
107
|
+
* typeof (new WeakSet()) // => 'object'
|
|
108
|
+
* typeof (new Date()) // => 'object'
|
|
109
|
+
* typeof window // => 'object'
|
|
110
|
+
* typeof document // => 'object'
|
|
111
|
+
* ```
|
|
112
|
+
*
|
|
113
|
+
* @see {@link isObject}, {@link isPlainObject}
|
|
114
|
+
*/
|
|
115
|
+
// oxlint-disable-next-line no-wrapper-object-types
|
|
116
|
+
export const isGeneralObject = (target: unknown): target is Object => {
|
|
117
|
+
return target !== null && typeof target === "object"
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Predicate whether the target is a plain object.
|
|
121
|
+
*
|
|
122
|
+
* A plain object is an object that is:
|
|
123
|
+
* - not `null`, not a `function`, not a `primitive` type,
|
|
124
|
+
* - not an `Array`, not a `RegExp`, not a `Date`, not a `Map`, not a `Set`, not a `WeakMap`,
|
|
125
|
+
* - not `window`, not a DOM `element`, not an `Error`,
|
|
126
|
+
* - not any other customize object type.
|
|
127
|
+
*
|
|
128
|
+
* @see {@link isObject}, {@link isGeneralObject}
|
|
129
|
+
*/
|
|
130
|
+
export const isPlainObject = (target: unknown): target is PlainObject => {
|
|
131
|
+
// 非 null、非 Function、非 Primitive
|
|
132
|
+
if (target === null || typeof target !== "object") {
|
|
133
|
+
return false
|
|
134
|
+
}
|
|
135
|
+
// 非 Array、非 Regexp、非 Date、非 Map、非 Set、非 Window、非 DOM、非 Error……
|
|
136
|
+
if (Object.prototype.toString.call(target) !== "[object Object]") {
|
|
137
|
+
return false
|
|
138
|
+
}
|
|
139
|
+
// 非其它自定义类实例对象,allow only plain object literal or Object.create(null)
|
|
140
|
+
// oxlint-disable-next-line no-unsafe-assignment
|
|
141
|
+
const proto = Object.getPrototypeOf(target)
|
|
142
|
+
return proto === Object.prototype || proto === null
|
|
143
|
+
}
|
|
144
|
+
export const isEmptyPlainObject = (target: unknown): target is PlainObject => {
|
|
145
|
+
return isPlainObject(target) && Reflect.ownKeys(target).length === 0
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function isArray<T>(target: T[]): target is T[]
|
|
149
|
+
export function isArray<T>(target: unknown): target is T[]
|
|
150
|
+
export function isArray<T>(target: unknown): target is T[] {
|
|
151
|
+
return Array.isArray(target)
|
|
152
|
+
}
|
|
153
|
+
export const isEmptyArray = (target: unknown): target is [] => {
|
|
154
|
+
return isArray(target) && target.length === 0
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function isArrayLike<T>(target: ArrayLike<T>): target is ArrayLike<T>
|
|
158
|
+
export function isArrayLike<T>(target: unknown): target is ArrayLike<T>
|
|
159
|
+
export function isArrayLike<T>(target: unknown): target is ArrayLike<T> {
|
|
160
|
+
return isGeneralObject(target) && ("length" in target) && isNumber(target.length)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export function isMap<K, V>(target: Map<K, V>): target is Map<K, V>
|
|
164
|
+
export function isMap<K, V>(target: unknown): target is Map<K, V>
|
|
165
|
+
export function isMap<K, V>(target: unknown): target is Map<K, V> {
|
|
166
|
+
return Object.prototype.toString.call(target) === "[object Map]"
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function isWeakMap<K extends object, V>(target: WeakMap<K, V>): target is WeakMap<K, V>
|
|
170
|
+
export function isWeakMap<K extends object, V>(target: unknown): target is WeakMap<K, V>
|
|
171
|
+
export function isWeakMap<K extends object, V>(target: unknown): target is WeakMap<K, V> {
|
|
172
|
+
return Object.prototype.toString.call(target) === "[object WeakMap]"
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function isSet<T>(target: Set<T>): target is Set<T>
|
|
176
|
+
export function isSet<T>(target: unknown): target is Set<T>
|
|
177
|
+
export function isSet<T>(target: unknown): target is Set<T> {
|
|
178
|
+
return Object.prototype.toString.call(target) === "[object Set]"
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function isWeakSet<T extends object>(target: WeakSet<T>): target is WeakSet<T>
|
|
182
|
+
export function isWeakSet<T extends object>(target: unknown): target is WeakSet<T>
|
|
183
|
+
export function isWeakSet<T extends object>(target: unknown): target is WeakSet<T> {
|
|
184
|
+
return Object.prototype.toString.call(target) === "[object WeakSet]"
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export const isDate = (target: unknown): target is Date => {
|
|
188
|
+
return Object.prototype.toString.call(target) === "[object Date]"
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export const isRegExp = (target: unknown): target is RegExp => {
|
|
192
|
+
return Object.prototype.toString.call(target) === "[object RegExp]"
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export const isError = (target: unknown): target is Error => {
|
|
196
|
+
return Object.prototype.toString.call(target) === "[object Error]"
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function isPromise<T>(target: Promise<T>): target is Promise<T>
|
|
200
|
+
export function isPromise<T>(target: unknown): target is Promise<T>
|
|
201
|
+
export function isPromise<T>(target: unknown): target is Promise<T> {
|
|
202
|
+
return Object.prototype.toString.call(target) === "[object Promise]"
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// oxlint-disable-next-line no-unsafe-function-type
|
|
206
|
+
export const isFunction = (target: unknown): target is Function => {
|
|
207
|
+
return typeof target === "function"
|
|
208
|
+
}
|
|
209
|
+
export const isAnyFunction = (target: unknown): target is AnyFunction => {
|
|
210
|
+
return isFunction(target)
|
|
211
|
+
}
|
|
212
|
+
export const isSyncFunction = (target: unknown): target is AnySyncFunction => {
|
|
213
|
+
return Object.prototype.toString.call(target) === "[object Function]"
|
|
214
|
+
}
|
|
215
|
+
export const isAsyncFunction = (target: unknown): target is AnyAsyncFunction => {
|
|
216
|
+
return Object.prototype.toString.call(target) === "[object AsyncFunction]"
|
|
217
|
+
}
|
|
218
|
+
export const isGeneratorFunction = (target: unknown): target is AnyGeneratorFunction => {
|
|
219
|
+
return Object.prototype.toString.call((target)) === "[object GeneratorFunction]"
|
|
220
|
+
}
|
|
221
|
+
export const isAsyncGeneratorFunction = (target: unknown): target is AnyAsyncGeneratorFunction => {
|
|
222
|
+
return Object.prototype.toString.call(target) === "[object AsyncGeneratorFunction]"
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol}
|
|
227
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator}
|
|
228
|
+
*/
|
|
229
|
+
export function isIterable<T>(target: Iterable<T>): target is Iterable<T>
|
|
230
|
+
export function isIterable<T>(target: unknown): target is Iterable<T>
|
|
231
|
+
export function isIterable<T>(target: unknown): target is Iterable<T> {
|
|
232
|
+
// oxlint-disable-next-line no-unsafe-type-assertion no-unsafe-member-access
|
|
233
|
+
return isGeneralObject(target) && typeof (target as any)[Symbol.iterator] === "function"
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator}
|
|
237
|
+
*/
|
|
238
|
+
export function isAsyncIterable<T>(target: AsyncIterable<T>): target is AsyncIterable<T>
|
|
239
|
+
export function isAsyncIterable<T>(target: unknown): target is AsyncIterable<T>
|
|
240
|
+
export function isAsyncIterable<T>(target: unknown): target is AsyncIterable<T> {
|
|
241
|
+
// oxlint-disable-next-line no-unsafe-type-assertion no-unsafe-member-access
|
|
242
|
+
return isGeneralObject(target) && typeof (target as any)[Symbol.asyncIterator] === "function"
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterator_protocol}
|
|
246
|
+
*/
|
|
247
|
+
export function isIterator<T, TReturn = unknown, TNext = undefined>(target: Iterator<T, TReturn, TNext>): target is Iterator<T, TReturn, TNext>
|
|
248
|
+
export function isIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is Iterator<T, TReturn, TNext>
|
|
249
|
+
export function isIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is Iterator<T, TReturn, TNext> {
|
|
250
|
+
// oxlint-disable-next-line no-unsafe-type-assertion no-unsafe-member-access
|
|
251
|
+
return isGeneralObject(target) && typeof (target as any).next === "function"
|
|
252
|
+
}
|
|
253
|
+
export function isAsyncIterator<T, TReturn = unknown, TNext = undefined>(target: AsyncIterator<T, TReturn, TNext>): target is AsyncIterator<T, TReturn, TNext>
|
|
254
|
+
export function isAsyncIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is AsyncIterator<T, TReturn, TNext>
|
|
255
|
+
export function isAsyncIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is AsyncIterator<T, TReturn, TNext> {
|
|
256
|
+
// oxlint-disable-next-line no-unsafe-type-assertion no-unsafe-member-access
|
|
257
|
+
return isGeneralObject(target) && typeof (target as any).next === "function"
|
|
258
|
+
}
|
|
259
|
+
export function isIterableIterator<T, TReturn = unknown, TNext = undefined>(target: IterableIterator<T>): target is IterableIterator<T, TReturn, TNext>
|
|
260
|
+
export function isIterableIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is IterableIterator<T, TReturn, TNext>
|
|
261
|
+
export function isIterableIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is IterableIterator<T> {
|
|
262
|
+
return isIterator<T, TReturn, TNext>(target) && isIterable<T>(target)
|
|
263
|
+
}
|
|
264
|
+
export function isAsyncIterableIterator<T, TReturn = unknown, TNext = undefined>(target: AsyncIterableIterator<T>): target is AsyncIterableIterator<T, TReturn, TNext>
|
|
265
|
+
export function isAsyncIterableIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is AsyncIterableIterator<T, TReturn, TNext>
|
|
266
|
+
export function isAsyncIterableIterator<T, TReturn = unknown, TNext = undefined>(target: unknown): target is AsyncIterableIterator<T> {
|
|
267
|
+
return isAsyncIterator<T, TReturn, TNext>(target) && isAsyncIterable<T>(target)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Check `target` and `Window` is both defined
|
|
272
|
+
* before use the `instanceof` operator to check `target` is instanceof `Window`.
|
|
273
|
+
*/
|
|
274
|
+
export const isWindow = (target: unknown): target is Window => {
|
|
275
|
+
return isGeneralObject(target) && isDefined(Window) && target instanceof Window
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Check `target` and `Element` is both defined
|
|
279
|
+
* before use the `instanceof` operator to check `target` is instanceof `Element`.
|
|
280
|
+
*/
|
|
281
|
+
export const isElement = (target: unknown): target is Element => {
|
|
282
|
+
return isGeneralObject(target) && isDefined(Element) && target instanceof Element
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Check `target` and `Node` is both defined
|
|
286
|
+
* before use the `instanceof` operator to check `target` is instanceof `Node`.
|
|
287
|
+
*/
|
|
288
|
+
export const isNode = (target: unknown): target is Node => {
|
|
289
|
+
return isGeneralObject(target) && isDefined(Node) && target instanceof Node
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Check `target` and `HTMLElement` is both defined
|
|
293
|
+
* before use the `instanceof` operator to check `target` is instanceof `HTMLElement`.
|
|
294
|
+
*/
|
|
295
|
+
export const isHTMLElement = (target: unknown): target is HTMLElement => {
|
|
296
|
+
return isGeneralObject(target) && isDefined(HTMLElement) && target instanceof HTMLElement
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Check `target` and `HTMLCollection` is both defined
|
|
300
|
+
* before use the `instanceof` operator to check `target` is instanceof `HTMLCollection`.
|
|
301
|
+
*/
|
|
302
|
+
export const isHTMLCollection = (target: unknown): target is HTMLCollection => {
|
|
303
|
+
return isGeneralObject(target) && isDefined(HTMLCollection) && target instanceof HTMLCollection
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Check `target` and `Document` is both defined
|
|
307
|
+
* before use the `instanceof` operator to check `target` is instanceof `Document`.
|
|
308
|
+
*/
|
|
309
|
+
export const isDocument = (target: unknown): target is Document => {
|
|
310
|
+
return isGeneralObject(target) && isDefined(Document) && target instanceof Document
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Check `target` and `EventTarget` is both defined
|
|
314
|
+
* before use the `instanceof` operator to check `target` is instanceof `EventTarget`.
|
|
315
|
+
*
|
|
316
|
+
* @see {@link https://developer.mozilla.org/zh-CN/docs/Web/API/Event}
|
|
317
|
+
*/
|
|
318
|
+
export const isEventTarget = (target: unknown): target is EventTarget => {
|
|
319
|
+
return isGeneralObject(target) && isDefined(EventTarget) && target instanceof EventTarget
|
|
320
|
+
}
|