type-plus 3.12.1 → 3.14.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/README.md +35 -33
- package/lib/ComposableTypes.d.ts +8 -0
- package/lib/ComposableTypes.js +3 -0
- package/lib/ComposableTypes.js.map +1 -0
- package/lib/JSONTypes.js +10 -5
- package/lib/JSONTypes.js.map +1 -1
- package/lib/assertion/assertType.d.ts +0 -46
- package/lib/assertion/assertType.js +4 -4
- package/lib/assertion/assertType.js.map +1 -1
- package/lib/class/isConstructor.js +2 -2
- package/lib/class/isConstructor.js.map +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/math/Subtract.d.ts +1 -1
- package/lib/nominal-types/Brand.js.map +1 -1
- package/lib/nominal-types/Flavor.js +1 -2
- package/lib/nominal-types/Flavor.js.map +1 -1
- package/lib/object/KnownKeys.d.ts +2 -1
- package/lib/object/KnownKeys.js +3 -0
- package/lib/object/KnownKeys.js.map +1 -1
- package/lib/object/facade.js +3 -0
- package/lib/object/facade.js.map +1 -1
- package/lib/object/getField.js.map +1 -1
- package/lib/object/hasKey.js.map +1 -1
- package/lib/object/mapProperties.js +1 -1
- package/lib/object/mapProperties.js.map +1 -1
- package/lib/object/omit.js +1 -1
- package/lib/object/omit.js.map +1 -1
- package/lib/object/pick.js +1 -1
- package/lib/object/pick.js.map +1 -1
- package/lib/object/typeOverrideIncompatible.js.map +1 -1
- package/lib/predicates/CanAssign.d.ts +2 -1
- package/lib/predicates/CanAssign.js.map +1 -1
- package/lib/predicates/index.d.ts +1 -0
- package/lib/predicates/index.js +1 -0
- package/lib/predicates/index.js.map +1 -1
- package/lib/predicates/isEmptyObject.d.ts +1 -0
- package/lib/predicates/isEmptyObject.js +3 -0
- package/lib/predicates/isEmptyObject.js.map +1 -0
- package/lib/predicates/isType.d.ts +4 -13
- package/lib/predicates/isType.js +3 -6
- package/lib/predicates/isType.js.map +1 -1
- package/lib/promise/isPromise.d.ts +1 -1
- package/lib/promise/isPromise.js +2 -1
- package/lib/promise/isPromise.js.map +1 -1
- package/lib/promise/mapSeries.js +1 -7
- package/lib/promise/mapSeries.js.map +1 -1
- package/lib/types/Number.js +10 -6
- package/lib/types/Number.js.map +1 -1
- package/lib/types/Object.d.ts +4 -20
- package/lib/types/Object.js +1 -1
- package/lib/types/Object.js.map +1 -1
- package/lib/types/String.js +10 -6
- package/lib/types/String.js.map +1 -1
- package/lib/types/Tuple.js +10 -6
- package/lib/types/Tuple.js.map +1 -1
- package/lib/types/Union.js +9 -5
- package/lib/types/Union.js.map +1 -1
- package/lib/types/analyze.js +3 -2
- package/lib/types/analyze.js.map +1 -1
- package/lib/types/check.js +2 -2
- package/lib/types/check.js.map +1 -1
- package/lib/types/conform.js +2 -2
- package/lib/types/conform.js.map +1 -1
- package/lib/types/getPlainAnalysisReport.js +28 -24
- package/lib/types/getPlainAnalysisReport.js.map +1 -1
- package/lib/types/optional.d.ts +4 -20
- package/lib/types/required.d.ts +8 -40
- package/lib/types/satisfy.js +2 -2
- package/lib/types/satisfy.js.map +1 -1
- package/libm/ComposableTypes.js +2 -0
- package/libm/ComposableTypes.js.map +1 -0
- package/libm/JSONTypes.js +1 -0
- package/libm/JSONTypes.js.map +1 -1
- package/libm/assertion/assertType.js.map +1 -1
- package/libm/class/isConstructor.js +2 -1
- package/libm/class/isConstructor.js.map +1 -1
- package/libm/index.js +1 -0
- package/libm/index.js.map +1 -1
- package/libm/nominal-types/Brand.js.map +1 -1
- package/libm/nominal-types/Flavor.js +1 -2
- package/libm/nominal-types/Flavor.js.map +1 -1
- package/libm/object/KnownKeys.js +3 -0
- package/libm/object/KnownKeys.js.map +1 -1
- package/libm/object/facade.js +3 -0
- package/libm/object/facade.js.map +1 -1
- package/libm/object/getField.js.map +1 -1
- package/libm/object/hasKey.js.map +1 -1
- package/libm/object/omit.js.map +1 -1
- package/libm/object/pick.js.map +1 -1
- package/libm/object/typeOverrideIncompatible.js.map +1 -1
- package/libm/predicates/CanAssign.js.map +1 -1
- package/libm/predicates/index.js +1 -0
- package/libm/predicates/index.js.map +1 -1
- package/libm/predicates/isEmptyObject.js +2 -0
- package/libm/predicates/isEmptyObject.js.map +1 -0
- package/libm/predicates/isType.js +4 -5
- package/libm/predicates/isType.js.map +1 -1
- package/libm/promise/isPromise.js +2 -1
- package/libm/promise/isPromise.js.map +1 -1
- package/libm/promise/mapSeries.js +1 -7
- package/libm/promise/mapSeries.js.map +1 -1
- package/package.json +26 -29
- package/src/ComposableTypes.spec.ts +29 -0
- package/src/ComposableTypes.ts +10 -0
- package/src/JSONTypes.ts +2 -1
- package/src/UnionToIntersection.ts +1 -1
- package/src/assertion/assertType.spec.ts +4 -1
- package/src/assertion/assertType.ts +2 -2
- package/src/class/AnyConstructor.spec.ts +2 -2
- package/src/class/isConstructor.spec.ts +7 -2
- package/src/class/isConstructor.ts +4 -3
- package/src/function/AnyFunction.spec.ts +9 -9
- package/src/functional/Maybe.spec.ts +2 -3
- package/src/functional/Maybe.ts +1 -0
- package/src/index.ts +1 -0
- package/src/math/Abs.spec.ts +1 -1
- package/src/math/Digit.spec.ts +2 -2
- package/src/math/Subtract.spec.ts +1 -1
- package/src/math/Subtract.ts +1 -1
- package/src/nominal-types/Brand.ts +3 -3
- package/src/nominal-types/Flavor.ts +3 -5
- package/src/object/ExcludePropType.spec.ts +1 -1
- package/src/object/KnownKeys.spec.ts +1 -1
- package/src/object/KnownKeys.ts +13 -5
- package/src/object/Partial.spec.ts +4 -5
- package/src/object/RecursiveIntersect.spec.ts +3 -3
- package/src/object/Required.spec.ts +2 -2
- package/src/object/facade.ts +3 -0
- package/src/object/getField.spec.ts +3 -3
- package/src/object/getField.ts +2 -2
- package/src/object/hasKey.ts +1 -1
- package/src/object/hasProperty.spec.ts +3 -3
- package/src/object/mapProperties.spec.ts +2 -2
- package/src/object/omit.spec.ts +5 -5
- package/src/object/omit.ts +1 -1
- package/src/object/pick.spec.ts +1 -1
- package/src/object/pick.ts +1 -1
- package/src/object/typeOverrideIncompatible.ts +1 -1
- package/src/predicates/CanAssign.ts +6 -3
- package/src/predicates/index.ts +1 -0
- package/src/predicates/isEmptyObject.spec.ts +15 -0
- package/src/predicates/isEmptyObject.ts +2 -0
- package/src/predicates/isType.spec.ts +2 -2
- package/src/predicates/isType.ts +7 -9
- package/src/promise/PromiseValue.spec.ts +1 -1
- package/src/promise/isPromise.ts +3 -2
- package/src/promise/mapSeries.ts +3 -7
- package/src/type-checker/AnyType.ts +1 -1
- package/src/types/satisfy.accept.ts +3 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RecursiveIntersect } from '..'
|
|
2
2
|
|
|
3
3
|
test('add object type to types', () => {
|
|
4
|
-
type U = { u: number }
|
|
4
|
+
type U = { u: number }
|
|
5
5
|
|
|
6
6
|
acceptU(addU('a'))
|
|
7
7
|
acceptU(addU(1))
|
|
@@ -29,8 +29,8 @@ test('add object type to types', () => {
|
|
|
29
29
|
// acceptU(comArr[0])
|
|
30
30
|
// acceptU(comArr[0].x)
|
|
31
31
|
|
|
32
|
-
function addU<T>(x: T): RecursiveIntersect<
|
|
33
|
-
return x as any
|
|
32
|
+
function addU<T>(x: T): RecursiveIntersect<T, U> {
|
|
33
|
+
return x as any as RecursiveIntersect<T, U>
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
function acceptU(x: U) {
|
|
@@ -7,7 +7,7 @@ test('make picked properties required', () => {
|
|
|
7
7
|
c: number,
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
const y: RequiredPick<Foo, 'a'> = { a: 1, c: 2 }
|
|
10
|
+
const y: RequiredPick<Foo, 'a'> = { a: 1, c: 2 }
|
|
11
11
|
|
|
12
12
|
assertType.noUndefined(y.a)
|
|
13
13
|
y.b = undefined
|
|
@@ -21,7 +21,7 @@ test('make not picked properties required', () => {
|
|
|
21
21
|
c: number,
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
const y: RequiredExcept<Foo, 'a'> = { b: 1, c: 2 }
|
|
24
|
+
const y: RequiredExcept<Foo, 'a'> = { b: 1, c: 2 }
|
|
25
25
|
|
|
26
26
|
y.a = undefined
|
|
27
27
|
assertType.noUndefined(y.b)
|
package/src/object/facade.ts
CHANGED
|
@@ -19,14 +19,17 @@ export function facade<T extends AnyRecord>(subject: T, ...props: (keyof T)[]) {
|
|
|
19
19
|
return props.reduce((p, k) => {
|
|
20
20
|
const prop = subject[k]
|
|
21
21
|
if (typeof prop === 'function') {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
|
22
23
|
p[k] = prop.bind(subject)
|
|
23
24
|
}
|
|
24
25
|
else {
|
|
25
26
|
Object.defineProperty(p, k, {
|
|
26
27
|
get() {
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
27
29
|
return subject[k]
|
|
28
30
|
},
|
|
29
31
|
set(value: any) {
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment
|
|
30
33
|
return subject[k] = value
|
|
31
34
|
},
|
|
32
35
|
})
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { getField } from '..'
|
|
2
2
|
|
|
3
3
|
test('support undefined', () => {
|
|
4
|
-
const sub: { a: number } | undefined = { a: 1 }
|
|
4
|
+
const sub: { a: number } | undefined = { a: 1 }
|
|
5
5
|
expect(getField(sub, 'a')).toBe(1)
|
|
6
6
|
})
|
|
7
7
|
|
|
8
8
|
test('support null', () => {
|
|
9
|
-
const sub: { a: number } | null = { a: 1 }
|
|
9
|
+
const sub: { a: number } | null = { a: 1 }
|
|
10
10
|
expect(getField(sub, 'a')).toBe(1)
|
|
11
11
|
})
|
|
12
12
|
|
|
@@ -16,6 +16,6 @@ test('can specify default value', () => {
|
|
|
16
16
|
})
|
|
17
17
|
|
|
18
18
|
test('get from union keys', () => {
|
|
19
|
-
const sub: { a: number, b: string } | { a: number, c: string } = { a: 1, b: 'b' }
|
|
19
|
+
const sub: { a: number, b: string } | { a: number, c: string } = { a: 1, b: 'b' }
|
|
20
20
|
expect(getField(sub, 'b')).toBe('b')
|
|
21
21
|
})
|
package/src/object/getField.ts
CHANGED
|
@@ -16,6 +16,6 @@ export function getField<
|
|
|
16
16
|
TX extends Exclude<T, undefined | null>,
|
|
17
17
|
K extends UnionKeys<TX>,
|
|
18
18
|
DV extends Exclude<TX[K], undefined>
|
|
19
|
-
>(subject: T, key: K, defaultValue?: DV)
|
|
20
|
-
return subject && (subject as
|
|
19
|
+
>(subject: T, key: K, defaultValue?: DV) {
|
|
20
|
+
return subject && (subject as unknown as { [k in K]: TX[K] | DV })[key] || defaultValue
|
|
21
21
|
}
|
package/src/object/hasKey.ts
CHANGED
|
@@ -3,5 +3,5 @@ import { AnyRecord } from './AnyRecord'
|
|
|
3
3
|
export type HasKey<T, K, Then = true, Else = false> = K extends keyof T ? Then : Else
|
|
4
4
|
|
|
5
5
|
export function hasKey<T extends AnyRecord, K extends string>(subject: T, ...keys: K[]): HasKey<T, K> {
|
|
6
|
-
return !keys.some(key => !subject[key]) as
|
|
6
|
+
return !keys.some(key => !subject[key]) as unknown as HasKey<T, K>
|
|
7
7
|
}
|
|
@@ -3,13 +3,13 @@ import { hasProperty } from '..'
|
|
|
3
3
|
test('hasProperty', () => {
|
|
4
4
|
type X = { name: string } & ({ a: 1 } | { b: 2 })
|
|
5
5
|
|
|
6
|
-
const x: X = { name: 'n', a: 1 }
|
|
6
|
+
const x: X = { name: 'n', a: 1 }
|
|
7
7
|
|
|
8
8
|
if (hasProperty(x, 'a'))
|
|
9
9
|
expect(x.a).toBe(1)
|
|
10
10
|
|
|
11
|
-
const y: X = { name: 'n', b: 2 }
|
|
11
|
+
const y: X = { name: 'n', b: 2 }
|
|
12
12
|
|
|
13
13
|
if (hasProperty(y, 'b'))
|
|
14
14
|
expect(y.b).toBe(2)
|
|
15
|
-
})
|
|
15
|
+
})
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { mapProperties } from '..'
|
|
2
2
|
|
|
3
3
|
test('basic usage', () => {
|
|
4
|
-
const actual = mapProperties({ a: 1, b: 2 }, (v, k) => k + (v * 2))
|
|
4
|
+
const actual = mapProperties({ a: 1, b: 2 }, (v, k) => k + String((v * 2)))
|
|
5
5
|
expect(actual).toEqual({ a: 'a2', b: 'b4' })
|
|
6
6
|
})
|
|
7
7
|
|
|
8
8
|
test('mixed type', () => {
|
|
9
|
-
const actual = mapProperties({ a: 1, b: 'b' }, (v, k) => k + v)
|
|
9
|
+
const actual = mapProperties({ a: 1, b: 'b' }, (v, k) => k + String(v))
|
|
10
10
|
expect(actual).toEqual({ a: 'a1', b: 'bb' })
|
|
11
11
|
})
|
|
12
12
|
|
package/src/object/omit.spec.ts
CHANGED
|
@@ -14,12 +14,12 @@ describe('Omit', () => {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
type Actual = Omit<Foo, 'c'>
|
|
17
|
-
const a: Actual = { a: 0, b: '' }
|
|
17
|
+
const a: Actual = { a: 0, b: '' }
|
|
18
18
|
assertType.isNumber(a.a)
|
|
19
19
|
assertType.isString(a.b)
|
|
20
20
|
|
|
21
21
|
type Revert = Omit<Foo, keyof Actual>
|
|
22
|
-
const r: Revert = { c: false }
|
|
22
|
+
const r: Revert = { c: false }
|
|
23
23
|
assertType.isBoolean(r.c)
|
|
24
24
|
})
|
|
25
25
|
|
|
@@ -38,7 +38,7 @@ describe('Omit', () => {
|
|
|
38
38
|
payload: string,
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
const x: Omit<Action, 'id'> = {
|
|
41
|
+
const x: Omit<Action, 'id'> = { type: 'return', payload: '' }
|
|
42
42
|
|
|
43
43
|
const actions: Action[] = []
|
|
44
44
|
|
|
@@ -92,13 +92,13 @@ describe('Except()', () => {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
type Actual = Except<Foo, 'c'>
|
|
95
|
-
const a: Actual = { a: 0, b: '' }
|
|
95
|
+
const a: Actual = { a: 0, b: '' }
|
|
96
96
|
assertType.isNumber(a.a)
|
|
97
97
|
assertType.isString(a.b)
|
|
98
98
|
|
|
99
99
|
// tslint:disable-next-line: deprecation
|
|
100
100
|
type Revert = Except<Foo, keyof Actual>
|
|
101
|
-
const r: Revert = { c: false }
|
|
101
|
+
const r: Revert = { c: false }
|
|
102
102
|
assertType.isBoolean(r.c)
|
|
103
103
|
})
|
|
104
104
|
})
|
package/src/object/omit.ts
CHANGED
package/src/object/pick.spec.ts
CHANGED
package/src/object/pick.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { NotExtendable } from './Extends'
|
|
2
|
+
import { IsEmptyObject } from './isEmptyObject'
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Can `A` assign to `B`
|
|
5
6
|
*/
|
|
6
7
|
export type CanAssign<A, B, Then = true, Else = false> =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
IsEmptyObject<A> extends true
|
|
9
|
+
? Record<string, unknown> extends B ? Then : Else
|
|
10
|
+
: boolean extends A
|
|
11
|
+
? (boolean extends B ? Then : Else)
|
|
12
|
+
: A extends B ? Then : Else
|
|
10
13
|
|
|
11
14
|
|
|
12
15
|
export type IsAssign<A, B, Then = true, Else = false> = CanAssign<A, B, Then, Else>
|
package/src/predicates/index.ts
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
|
+
import { IsEmptyObject } from '..'
|
|
3
|
+
import { isType } from './isType'
|
|
4
|
+
|
|
5
|
+
test('true for {}', () => {
|
|
6
|
+
isType.t<IsEmptyObject<{}>>()
|
|
7
|
+
})
|
|
8
|
+
test('false for everything else', () => {
|
|
9
|
+
isType.f<IsEmptyObject<undefined>>()
|
|
10
|
+
isType.f<IsEmptyObject<false>>()
|
|
11
|
+
isType.f<IsEmptyObject<0>>()
|
|
12
|
+
isType.f<IsEmptyObject<''>>()
|
|
13
|
+
isType.f<IsEmptyObject<{ a: 1 }>>()
|
|
14
|
+
})
|
|
15
|
+
|
|
@@ -27,7 +27,7 @@ describe('isType()', () => {
|
|
|
27
27
|
assertType<boolean>(s)
|
|
28
28
|
})
|
|
29
29
|
test('exclude type if type guard fails', () => {
|
|
30
|
-
const s: string | number = 1
|
|
30
|
+
const s: string | number = 1
|
|
31
31
|
if (isType<string>(s, s => typeof s === 'string')) {
|
|
32
32
|
assertType<string>(s)
|
|
33
33
|
}
|
|
@@ -44,7 +44,7 @@ describe('isType()', () => {
|
|
|
44
44
|
})
|
|
45
45
|
test('Class as validator fails', () => {
|
|
46
46
|
class Foo { a() { } }
|
|
47
|
-
const s: Foo | number = 1
|
|
47
|
+
const s: Foo | number = 1
|
|
48
48
|
if (isType(s, Foo)) {
|
|
49
49
|
assertType<Foo>(s)
|
|
50
50
|
}
|
package/src/predicates/isType.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { isConstructor } from '../class'
|
|
1
|
+
import { AnyConstructor, isConstructor } from '../class'
|
|
2
2
|
import { Equal } from './Equal'
|
|
3
3
|
|
|
4
4
|
export function isType<T>(subject: T): subject is T
|
|
5
5
|
export function isType<T>(subject: unknown, validator: (s: T) => boolean): subject is T
|
|
6
|
-
export function isType<T extends
|
|
7
|
-
export function isType(subject:
|
|
6
|
+
export function isType<T extends AnyConstructor>(subject: unknown, constructor: T): subject is InstanceType<T>
|
|
7
|
+
export function isType(subject: unknown, validator?: AnyConstructor | ((s: unknown) => boolean)) {
|
|
8
8
|
if (validator) {
|
|
9
9
|
if (isConstructor(validator))
|
|
10
10
|
return subject instanceof validator
|
|
@@ -14,13 +14,11 @@ export function isType(subject: any, validator?: any) {
|
|
|
14
14
|
return true
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
isType.t = function <T extends true>(subject: T = sym as any) {
|
|
20
|
-
return (subject as any) === sym || subject === true
|
|
17
|
+
isType.t = function <T extends true>(subject?: T) {
|
|
18
|
+
return subject === undefined || subject === true
|
|
21
19
|
}
|
|
22
|
-
isType.f = function <T extends false>(subject
|
|
23
|
-
return
|
|
20
|
+
isType.f = function <T extends false>(subject?: T) {
|
|
21
|
+
return subject === undefined || subject === false
|
|
24
22
|
}
|
|
25
23
|
|
|
26
24
|
/**
|
package/src/promise/isPromise.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export function isPromise<R = any>(subject:
|
|
2
|
-
|
|
1
|
+
export function isPromise<R = any>(subject: unknown): subject is Promise<R> {
|
|
2
|
+
// @ts-ignore
|
|
3
|
+
return !!subject && typeof subject['then'] === 'function'
|
|
3
4
|
}
|
package/src/promise/mapSeries.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
export function mapSeries<R, T = any>(values: T[], fn: (value: T) => Promise<R>): Promise<R[]> {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
results.push(r)
|
|
6
|
-
return results
|
|
7
|
-
})
|
|
8
|
-
}, Promise.resolve() as any)
|
|
2
|
+
return values.reduce(
|
|
3
|
+
(p, v) => p.then(r => fn(v).then(v => (r.push(v), r))),
|
|
4
|
+
Promise.resolve<R[]>([]))
|
|
9
5
|
}
|
|
@@ -29,7 +29,9 @@ const eslint = T.object.create({
|
|
|
29
29
|
|
|
30
30
|
baseline('fixtures/eslint', ({ caseName, caseFolder }) => {
|
|
31
31
|
test(`eslint ${caseName}`, () => {
|
|
32
|
-
const config = JSON.parse(
|
|
32
|
+
const config: unknown = JSON.parse(
|
|
33
|
+
fs.readFileSync(`${path.join(caseFolder, caseName)}`, 'utf-8')
|
|
34
|
+
)
|
|
33
35
|
|
|
34
36
|
if (!T.satisfy(eslint, config)) fail('should satisfy')
|
|
35
37
|
})
|