type-plus 4.7.0 → 4.8.2
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 +1 -0
- package/cjs/math/GreaterThan.d.ts +1 -1
- package/cjs/object/split.d.ts +1 -1
- package/cjs/utils/as.d.ts +4 -0
- package/cjs/utils/as.js +8 -1
- package/cjs/utils/as.js.map +1 -1
- package/esm/utils/as.js +6 -0
- package/esm/utils/as.js.map +1 -1
- package/package.json +1 -1
- package/ts/math/GreaterThan.spec.ts +43 -40
- package/ts/math/GreaterThan.ts +3 -3
- package/ts/object/split.spec.ts +18 -0
- package/ts/object/split.ts +1 -1
- package/ts/utils/as.spec.ts +13 -1
- package/ts/utils/as.ts +10 -0
package/README.md
CHANGED
|
@@ -427,6 +427,7 @@ So you may encounter some weird behavior if your logic is complex.
|
|
|
427
427
|
|
|
428
428
|
### Utility Functions
|
|
429
429
|
|
|
430
|
+
- `amend(subject)...`: amend subject as union or intersect of `T`.
|
|
430
431
|
- `facade(subject, ...props)`: create a facade of `subject`.
|
|
431
432
|
- `getField(subject, key, defaultValue)`: get a field from a subject. Works against nullable and optional subject.
|
|
432
433
|
- `hasKey()`: function of `HasKey`.
|
|
@@ -7,5 +7,5 @@ import type { Max } from './Max';
|
|
|
7
7
|
export declare type GreaterThan<A extends number, B extends number, Fail = never> = And<And<IsPositive<A>, IsWhole<A>>, And<IsPositive<B>, IsWhole<B>>> extends false ? Fail : number extends A ? Fail : number extends B ? Fail : Equal<A, B> extends true ? false : GreaterThan.OnPositiveWhole<A, B>;
|
|
8
8
|
export declare namespace GreaterThan {
|
|
9
9
|
type OnPositiveWhole<A extends number, B extends number> = (DigitArray.FromNumber<A> extends infer DA ? DA extends number[] ? DigitArray.FromNumber<B> extends infer DB ? DB extends number[] ? Max<DA['length'], DB['length']> extends infer M ? M extends number ? PadLeft<DA, M, 0> extends infer PDA ? PDA extends number[] ? PadLeft<DB, M, 0> extends infer PDB ? PDB extends number[] ? OnDigitArray<PDA, PDB> : never : never : never : never : never : never : never : never : never : never);
|
|
10
|
-
type OnDigitArray<DA extends number[], DB extends number[]> = (Equal<Head<DA>, Head<DB>> extends true ? OnDigitArray<Tail<DA>, Tail<DB>>
|
|
10
|
+
type OnDigitArray<DA extends number[], DB extends number[]> = (Equal<Head<DA>, Head<DB>> extends true ? OnDigitArray<Tail<DA>, Tail<DB>> : Digit.GreaterThan<Head<DA>, Head<DB>>);
|
|
11
11
|
}
|
package/cjs/object/split.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ declare type Splitter<T extends AnyRecord> = Partial<{
|
|
|
4
4
|
[k in keyof T]: T[k] | undefined;
|
|
5
5
|
}>;
|
|
6
6
|
export declare type Split<T extends AnyRecord, S extends AnyRecord> = {
|
|
7
|
-
[k in keyof S]
|
|
7
|
+
[k in keyof S]-?: S[k] extends undefined ? T[k] : NonNullable<T[k]> | S[k];
|
|
8
8
|
};
|
|
9
9
|
export declare function split<T extends AnyRecord, S1 extends Splitter<T>>(target: T, split1: S1): [
|
|
10
10
|
Split<T, S1>,
|
package/cjs/utils/as.d.ts
CHANGED
package/cjs/utils/as.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.asAny = exports.as = void 0;
|
|
3
|
+
exports.amend = exports.asAny = exports.as = void 0;
|
|
4
4
|
function as(subject) {
|
|
5
5
|
return subject;
|
|
6
6
|
}
|
|
@@ -9,4 +9,11 @@ function asAny(subject) {
|
|
|
9
9
|
return subject;
|
|
10
10
|
}
|
|
11
11
|
exports.asAny = asAny;
|
|
12
|
+
function amend(subject) {
|
|
13
|
+
return {
|
|
14
|
+
union: function () { return subject; },
|
|
15
|
+
intersect: function () { return subject; }
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
exports.amend = amend;
|
|
12
19
|
//# sourceMappingURL=as.js.map
|
package/cjs/utils/as.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"as.js","sourceRoot":"","sources":["../../ts/utils/as.ts"],"names":[],"mappings":";;;AAAA,SAAgB,EAAE,CAAI,OAAgB;IACpC,OAAO,OAAY,CAAA;AACrB,CAAC;AAFD,gBAEC;AAED,SAAgB,KAAK,CAAC,OAAgB;IACpC,OAAO,OAAO,CAAA;AAChB,CAAC;AAFD,sBAEC"}
|
|
1
|
+
{"version":3,"file":"as.js","sourceRoot":"","sources":["../../ts/utils/as.ts"],"names":[],"mappings":";;;AAAA,SAAgB,EAAE,CAAI,OAAgB;IACpC,OAAO,OAAY,CAAA;AACrB,CAAC;AAFD,gBAEC;AAED,SAAgB,KAAK,CAAC,OAAgB;IACpC,OAAO,OAAO,CAAA;AAChB,CAAC;AAFD,sBAEC;AAKD,SAAgB,KAAK,CAAI,OAAU;IACjC,OAAO;QACL,KAAK,EAAL,cAAoB,OAAO,OAAgB,CAAA,CAAC,CAAC;QAC7C,SAAS,EAAT,cAAwB,OAAO,OAAgB,CAAA,CAAC,CAAC;KAClD,CAAA;AACH,CAAC;AALD,sBAKC"}
|
package/esm/utils/as.js
CHANGED
package/esm/utils/as.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"as.js","sourceRoot":"","sources":["../../ts/utils/as.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,EAAE,CAAI,OAAgB;IACpC,OAAO,OAAY,CAAA;AACrB,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,OAAgB;IACpC,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
1
|
+
{"version":3,"file":"as.js","sourceRoot":"","sources":["../../ts/utils/as.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,EAAE,CAAI,OAAgB;IACpC,OAAO,OAAY,CAAA;AACrB,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,OAAgB;IACpC,OAAO,OAAO,CAAA;AAChB,CAAC;AAKD,MAAM,UAAU,KAAK,CAAI,OAAU;IACjC,OAAO;QACL,KAAK,KAAe,OAAO,OAAgB,CAAA,CAAC,CAAC;QAC7C,SAAS,KAAe,OAAO,OAAgB,CAAA,CAAC,CAAC;KAClD,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,40 +1,43 @@
|
|
|
1
|
-
import { GreaterThan, isType } from '..'
|
|
2
|
-
|
|
3
|
-
test('only support positive and whole number', () => {
|
|
4
|
-
isType.equal<true, never, GreaterThan<0.1, 1>>()
|
|
5
|
-
isType.equal<true, never, GreaterThan<-1, 1>>()
|
|
6
|
-
isType.equal<true, never, GreaterThan<1, 0.1>>()
|
|
7
|
-
isType.equal<true, never, GreaterThan<1, -1>>()
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
test('number gets never', () => {
|
|
11
|
-
isType.equal<true, never, GreaterThan<number, 1>>()
|
|
12
|
-
isType.equal<true, never, GreaterThan<1, number>>()
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
test('override Fail case', () => {
|
|
16
|
-
isType.equal<true, number, GreaterThan<number, 1, number>>()
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
test('n > n is false', () => {
|
|
20
|
-
isType.f<GreaterThan<0, 0>>()
|
|
21
|
-
isType.f<GreaterThan<1, 1>>()
|
|
22
|
-
isType.f<GreaterThan<12, 12>>()
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
test('with same number of digits', () => {
|
|
26
|
-
isType.t<GreaterThan<1, 0>>()
|
|
27
|
-
isType.t<GreaterThan<22, 11>>()
|
|
28
|
-
isType.t<GreaterThan<20, 19>>()
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
isType.f<GreaterThan<
|
|
32
|
-
isType.f<GreaterThan<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
isType.
|
|
39
|
-
isType.
|
|
40
|
-
|
|
1
|
+
import { GreaterThan, isType } from '..'
|
|
2
|
+
|
|
3
|
+
test('only support positive and whole number', () => {
|
|
4
|
+
isType.equal<true, never, GreaterThan<0.1, 1>>()
|
|
5
|
+
isType.equal<true, never, GreaterThan<-1, 1>>()
|
|
6
|
+
isType.equal<true, never, GreaterThan<1, 0.1>>()
|
|
7
|
+
isType.equal<true, never, GreaterThan<1, -1>>()
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test('number gets never', () => {
|
|
11
|
+
isType.equal<true, never, GreaterThan<number, 1>>()
|
|
12
|
+
isType.equal<true, never, GreaterThan<1, number>>()
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
test('override Fail case', () => {
|
|
16
|
+
isType.equal<true, number, GreaterThan<number, 1, number>>()
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
test('n > n is false', () => {
|
|
20
|
+
isType.f<GreaterThan<0, 0>>()
|
|
21
|
+
isType.f<GreaterThan<1, 1>>()
|
|
22
|
+
isType.f<GreaterThan<12, 12>>()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
test('with same number of digits', () => {
|
|
26
|
+
isType.t<GreaterThan<1, 0>>()
|
|
27
|
+
isType.t<GreaterThan<22, 11>>()
|
|
28
|
+
isType.t<GreaterThan<20, 19>>()
|
|
29
|
+
isType.t<GreaterThan<19, 10>>()
|
|
30
|
+
|
|
31
|
+
isType.f<GreaterThan<0, 1>>()
|
|
32
|
+
isType.f<GreaterThan<11, 22>>()
|
|
33
|
+
isType.f<GreaterThan<19, 20>>()
|
|
34
|
+
isType.f<GreaterThan<10, 19>>()
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
test('with different number of digits', () => {
|
|
38
|
+
isType.f<GreaterThan<0, 1>>()
|
|
39
|
+
isType.f<GreaterThan<9, 100>>()
|
|
40
|
+
isType.t<GreaterThan<10, 1>>()
|
|
41
|
+
isType.t<GreaterThan<123, 32>>()
|
|
42
|
+
isType.t<GreaterThan<123, 13>>()
|
|
43
|
+
})
|
package/ts/math/GreaterThan.ts
CHANGED
|
@@ -31,8 +31,8 @@ export namespace GreaterThan {
|
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
export type OnDigitArray<DA extends number[], DB extends number[]> = (
|
|
34
|
-
Equal<Head<DA>, Head<DB>> extends true
|
|
35
|
-
OnDigitArray<Tail<DA>, Tail<DB>>
|
|
36
|
-
Digit.GreaterThan<Head<DA>, Head<DB>>
|
|
34
|
+
Equal<Head<DA>, Head<DB>> extends true
|
|
35
|
+
? OnDigitArray<Tail<DA>, Tail<DB>>
|
|
36
|
+
: Digit.GreaterThan<Head<DA>, Head<DB>>
|
|
37
37
|
)
|
|
38
38
|
}
|
package/ts/object/split.spec.ts
CHANGED
|
@@ -35,6 +35,24 @@ test('can default with null', () => {
|
|
|
35
35
|
isType.equal<true, number | null, typeof a>()
|
|
36
36
|
})
|
|
37
37
|
|
|
38
|
+
test('remove optional/undefined when default is provided', () => {
|
|
39
|
+
interface S {
|
|
40
|
+
variant?: 'abc' | 'def'
|
|
41
|
+
}
|
|
42
|
+
const s: S = {}
|
|
43
|
+
const [a] = split(s, { variant: 'def' })
|
|
44
|
+
isType.equal<true, 'abc' | 'def', typeof a.variant>()
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
test('keep undefined when default is undefined', () => {
|
|
48
|
+
interface S {
|
|
49
|
+
variant?: 'abc' | 'def'
|
|
50
|
+
}
|
|
51
|
+
const s: S = {}
|
|
52
|
+
const [a] = split(s, { variant: undefined })
|
|
53
|
+
isType.equal<true, 'abc' | 'def' | undefined, typeof a.variant>()
|
|
54
|
+
})
|
|
55
|
+
|
|
38
56
|
|
|
39
57
|
test('can default with false', () => {
|
|
40
58
|
const s: { a?: number | boolean } = {}
|
package/ts/object/split.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { reduceByKey } from './reduceKey'
|
|
|
4
4
|
|
|
5
5
|
type Splitter<T extends AnyRecord> = Partial<{ [k in keyof T]: T[k] | undefined }>
|
|
6
6
|
export type Split<T extends AnyRecord, S extends AnyRecord> = {
|
|
7
|
-
[k in keyof S]
|
|
7
|
+
[k in keyof S]-?: S[k] extends undefined ? T[k] : NonNullable<T[k]> | S[k]
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
/**
|
package/ts/utils/as.spec.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { as, asAny, isType } from '..'
|
|
1
|
+
import { amend, as, asAny, isType } from '..'
|
|
2
2
|
|
|
3
3
|
describe('as<T>()', () => {
|
|
4
4
|
test('defaults subject type to unknown', () => {
|
|
@@ -31,3 +31,15 @@ describe('asAny()', () => {
|
|
|
31
31
|
})
|
|
32
32
|
})
|
|
33
33
|
|
|
34
|
+
describe('amend<T>()', () => {
|
|
35
|
+
test('assert subject as (subject & T)', () => {
|
|
36
|
+
const s = { a: 1 }
|
|
37
|
+
const a = amend(s).union<{ b: string }>()
|
|
38
|
+
isType.equal<true, { a: number } & { b: string }, typeof a>()
|
|
39
|
+
})
|
|
40
|
+
test('assert subject as (subject | T)', () => {
|
|
41
|
+
const s = { a: 1 }
|
|
42
|
+
const a = amend(s).intersect<{ b: string }>()
|
|
43
|
+
isType.equal<true, { a: number } | { b: string }, typeof a>()
|
|
44
|
+
})
|
|
45
|
+
})
|
package/ts/utils/as.ts
CHANGED
|
@@ -5,3 +5,13 @@ export function as<T>(subject: unknown): T {
|
|
|
5
5
|
export function asAny(subject: unknown): any {
|
|
6
6
|
return subject
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* amend `subject` with type `T`
|
|
11
|
+
*/
|
|
12
|
+
export function amend<S>(subject: S) {
|
|
13
|
+
return {
|
|
14
|
+
union<T>(): T & S { return subject as T & S },
|
|
15
|
+
intersect<T>(): T | S { return subject as T | S }
|
|
16
|
+
}
|
|
17
|
+
}
|