type-plus 4.12.1 → 4.13.1

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 CHANGED
@@ -380,6 +380,8 @@ JSONTypes.get<string>(someJson, 'a', 'b', 1, 'c') // miku
380
380
  - `BNotA<A, B>`: flip of `ANotB`
381
381
  - `as<T>(subject)`: assert `subject` as `T`. Avoid ASI issues such as `;(x as T).abc`
382
382
  - `asAny(subject)`: assert `subject` as `any`. Avoid ASI issue such as `;(x as any).abc`
383
+ - `EitherAnd<A, B, [C, D]>`: combines 2 to 4 types as `A | B | (A & B)`. This is useful for combining options. **Deprecated**. Renamed to `EitherOrBoth`.
384
+ - `EitherOrBoth<A, B, [C, D]>`: combines 2 to 4 types as `A | B | (A & B)`. This is useful for combining options.
383
385
  - `Except<T, K>`: Deprecated. Same as `Omit<T, K>`.
384
386
  - `ExcludePropType<T, U>`: excludes type `U` from properties in `T`.
385
387
  - `KeyofOptional<T>`: `keyof` that works with `Record<any, any> | undefined`.
@@ -2,4 +2,41 @@ export * from './as.js';
2
2
  export type { NonNull } from './NonNull.js';
3
3
  export type { NonUndefined } from './NonUndefined.js';
4
4
  export type { Widen } from './Widen.js';
5
+ /**
6
+ * `A` | `B` | `A & B`.
7
+ * Supports up to 4 types, and it is composable.
8
+ * This is useful when you want to compose multiple options together,
9
+ * while preserving their required field and structure.
10
+ * If the types overlaps each other, you may run into some corner cases.
11
+ * But in general usage it should work as expected.
12
+ * @example
13
+ * type A = { src: string, minify?: boolean }
14
+ * type B = { logLevel: number }
15
+ * function config(options: EitherAnd<A, B>) { }
16
+ *
17
+ * config({ logLevel: 1 })
18
+ * config({ src: 'src' })
19
+ * config({ src: 'src', minify: false })
20
+ * config({ minify: false }) // INVALID
21
+ */
22
+ export declare type EitherOrBoth<A, B, C = void, D = void> = C extends void ? A | B | A & B : (D extends void ? A | B | C | A & B | A & C | B & C | A & B & C : A | B | C | D | A & B | A & C | A & D | B & C | B & D | C & D | A & B & C | A & B & D | A & C & D | B & C & D | A & B & C & D);
23
+ /**
24
+ * `A` | `B` | `A & B`.
25
+ * Supports up to 4 types, and it is composable.
26
+ * This is useful when you want to compose multiple options together,
27
+ * while preserving their required field and structure.
28
+ * If the types overlaps each other, you may run into some corner cases.
29
+ * But in general usage it should work as expected.
30
+ * @deprecated renamed to `EitherOrBoth`
31
+ * @example
32
+ * type A = { src: string, minify?: boolean }
33
+ * type B = { logLevel: number }
34
+ * function config(options: EitherAnd<A, B>) { }
35
+ *
36
+ * config({ logLevel: 1 })
37
+ * config({ src: 'src' })
38
+ * config({ src: 'src', minify: false })
39
+ * config({ minify: false }) // INVALID
40
+ */
41
+ export declare type EitherAnd<A, B, C = void, D = void> = EitherOrBoth<A, B, C, D>;
5
42
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../ts/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../ts/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEvC;;;;;;;;;;;;;;;;GAgBG;AACH,oBAAY,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,IAAI,GAC/D,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GACb,CAAC,CAAC,SAAS,IAAI,GACb,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAC7C,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GACf,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAC7C,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAC7C,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CACd,CAAA;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACF,oBAAY,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.spec.d.ts","sourceRoot":"","sources":["../../ts/utils/index.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var index_js_1 = require("../index.js");
4
+ describe('Either<A, B>', function () {
5
+ it('allows just A', function () {
6
+ index_js_1.isType.equal();
7
+ index_js_1.isType.equal();
8
+ index_js_1.isType.equal();
9
+ index_js_1.isType.equal();
10
+ });
11
+ it('allows just B', function () {
12
+ index_js_1.isType.equal();
13
+ index_js_1.isType.equal();
14
+ index_js_1.isType.equal();
15
+ index_js_1.isType.equal();
16
+ });
17
+ it('allows A & B', function () {
18
+ index_js_1.isType.equal();
19
+ index_js_1.isType.equal();
20
+ index_js_1.isType.equal();
21
+ index_js_1.isType.equal();
22
+ index_js_1.isType.equal();
23
+ index_js_1.isType.equal();
24
+ index_js_1.isType.equal();
25
+ index_js_1.isType.equal();
26
+ });
27
+ it('can use isType() to type guard the value', function () {
28
+ function foo(o) {
29
+ if ((0, index_js_1.isType)(o, function (o) { return typeof o.a === 'number'; })) {
30
+ index_js_1.isType.equal();
31
+ }
32
+ else {
33
+ throw new Error('should not reach');
34
+ }
35
+ }
36
+ foo({ a: 1 });
37
+ });
38
+ it('will make sure required field to be filled in when specifying optional field', function () {
39
+ index_js_1.isType.equal();
40
+ index_js_1.isType.equal();
41
+ });
42
+ it('allows A, B, C', function () {
43
+ index_js_1.isType.equal();
44
+ index_js_1.isType.equal();
45
+ index_js_1.isType.equal();
46
+ index_js_1.isType.equal();
47
+ index_js_1.isType.equal();
48
+ index_js_1.isType.equal();
49
+ index_js_1.isType.equal();
50
+ index_js_1.isType.equal();
51
+ });
52
+ it('allows A, B, C, D', function () {
53
+ index_js_1.isType.equal();
54
+ index_js_1.isType.equal();
55
+ index_js_1.isType.equal();
56
+ index_js_1.isType.equal();
57
+ index_js_1.isType.equal();
58
+ index_js_1.isType.equal();
59
+ index_js_1.isType.equal();
60
+ index_js_1.isType.equal();
61
+ index_js_1.isType.equal();
62
+ index_js_1.isType.equal();
63
+ index_js_1.isType.equal();
64
+ index_js_1.isType.equal();
65
+ index_js_1.isType.equal();
66
+ index_js_1.isType.equal();
67
+ index_js_1.isType.equal();
68
+ index_js_1.isType.equal();
69
+ index_js_1.isType.equal();
70
+ index_js_1.isType.equal();
71
+ index_js_1.isType.equal();
72
+ });
73
+ it('can compose', function () {
74
+ index_js_1.isType.equal();
75
+ index_js_1.isType.equal();
76
+ index_js_1.isType.equal();
77
+ index_js_1.isType.equal();
78
+ index_js_1.isType.equal();
79
+ });
80
+ });
81
+ //# sourceMappingURL=index.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../../ts/utils/index.spec.ts"],"names":[],"mappings":"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"}
@@ -2,4 +2,41 @@ export * from './as.js';
2
2
  export type { NonNull } from './NonNull.js';
3
3
  export type { NonUndefined } from './NonUndefined.js';
4
4
  export type { Widen } from './Widen.js';
5
+ /**
6
+ * `A` | `B` | `A & B`.
7
+ * Supports up to 4 types, and it is composable.
8
+ * This is useful when you want to compose multiple options together,
9
+ * while preserving their required field and structure.
10
+ * If the types overlaps each other, you may run into some corner cases.
11
+ * But in general usage it should work as expected.
12
+ * @example
13
+ * type A = { src: string, minify?: boolean }
14
+ * type B = { logLevel: number }
15
+ * function config(options: EitherAnd<A, B>) { }
16
+ *
17
+ * config({ logLevel: 1 })
18
+ * config({ src: 'src' })
19
+ * config({ src: 'src', minify: false })
20
+ * config({ minify: false }) // INVALID
21
+ */
22
+ export declare type EitherOrBoth<A, B, C = void, D = void> = C extends void ? A | B | A & B : (D extends void ? A | B | C | A & B | A & C | B & C | A & B & C : A | B | C | D | A & B | A & C | A & D | B & C | B & D | C & D | A & B & C | A & B & D | A & C & D | B & C & D | A & B & C & D);
23
+ /**
24
+ * `A` | `B` | `A & B`.
25
+ * Supports up to 4 types, and it is composable.
26
+ * This is useful when you want to compose multiple options together,
27
+ * while preserving their required field and structure.
28
+ * If the types overlaps each other, you may run into some corner cases.
29
+ * But in general usage it should work as expected.
30
+ * @deprecated renamed to `EitherOrBoth`
31
+ * @example
32
+ * type A = { src: string, minify?: boolean }
33
+ * type B = { logLevel: number }
34
+ * function config(options: EitherAnd<A, B>) { }
35
+ *
36
+ * config({ logLevel: 1 })
37
+ * config({ src: 'src' })
38
+ * config({ src: 'src', minify: false })
39
+ * config({ minify: false }) // INVALID
40
+ */
41
+ export declare type EitherAnd<A, B, C = void, D = void> = EitherOrBoth<A, B, C, D>;
5
42
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../ts/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../ts/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,YAAY,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3C,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AACrD,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEvC;;;;;;;;;;;;;;;;GAgBG;AACH,oBAAY,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,SAAS,IAAI,GAC/D,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GACb,CAAC,CAAC,SAAS,IAAI,GACb,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAC7C,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GACf,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAC7C,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAC7C,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CACd,CAAA;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACF,oBAAY,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.spec.d.ts","sourceRoot":"","sources":["../../ts/utils/index.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,79 @@
1
+ import { isType } from '../index.js';
2
+ describe('Either<A, B>', () => {
3
+ it('allows just A', () => {
4
+ isType.equal();
5
+ isType.equal();
6
+ isType.equal();
7
+ isType.equal();
8
+ });
9
+ it('allows just B', () => {
10
+ isType.equal();
11
+ isType.equal();
12
+ isType.equal();
13
+ isType.equal();
14
+ });
15
+ it('allows A & B', () => {
16
+ isType.equal();
17
+ isType.equal();
18
+ isType.equal();
19
+ isType.equal();
20
+ isType.equal();
21
+ isType.equal();
22
+ isType.equal();
23
+ isType.equal();
24
+ });
25
+ it('can use isType() to type guard the value', () => {
26
+ function foo(o) {
27
+ if (isType(o, o => typeof o.a === 'number')) {
28
+ isType.equal();
29
+ }
30
+ else {
31
+ throw new Error('should not reach');
32
+ }
33
+ }
34
+ foo({ a: 1 });
35
+ });
36
+ it('will make sure required field to be filled in when specifying optional field', () => {
37
+ isType.equal();
38
+ isType.equal();
39
+ });
40
+ it('allows A, B, C', () => {
41
+ isType.equal();
42
+ isType.equal();
43
+ isType.equal();
44
+ isType.equal();
45
+ isType.equal();
46
+ isType.equal();
47
+ isType.equal();
48
+ isType.equal();
49
+ });
50
+ it('allows A, B, C, D', () => {
51
+ isType.equal();
52
+ isType.equal();
53
+ isType.equal();
54
+ isType.equal();
55
+ isType.equal();
56
+ isType.equal();
57
+ isType.equal();
58
+ isType.equal();
59
+ isType.equal();
60
+ isType.equal();
61
+ isType.equal();
62
+ isType.equal();
63
+ isType.equal();
64
+ isType.equal();
65
+ isType.equal();
66
+ isType.equal();
67
+ isType.equal();
68
+ isType.equal();
69
+ isType.equal();
70
+ });
71
+ it('can compose', () => {
72
+ isType.equal();
73
+ isType.equal();
74
+ isType.equal();
75
+ isType.equal();
76
+ isType.equal();
77
+ });
78
+ });
79
+ //# sourceMappingURL=index.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../../ts/utils/index.spec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-plus",
3
- "version": "4.12.1",
3
+ "version": "4.13.1",
4
4
  "description": "Provides additional types for TypeScript.",
5
5
  "homepage": "https://github.com/unional/type-plus",
6
6
  "bugs": {
package/ts/utils/index.ts CHANGED
@@ -2,3 +2,50 @@ export * from './as.js'
2
2
  export type { NonNull } from './NonNull.js'
3
3
  export type { NonUndefined } from './NonUndefined.js'
4
4
  export type { Widen } from './Widen.js'
5
+
6
+ /**
7
+ * `A` | `B` | `A & B`.
8
+ * Supports up to 4 types, and it is composable.
9
+ * This is useful when you want to compose multiple options together,
10
+ * while preserving their required field and structure.
11
+ * If the types overlaps each other, you may run into some corner cases.
12
+ * But in general usage it should work as expected.
13
+ * @example
14
+ * type A = { src: string, minify?: boolean }
15
+ * type B = { logLevel: number }
16
+ * function config(options: EitherAnd<A, B>) { }
17
+ *
18
+ * config({ logLevel: 1 })
19
+ * config({ src: 'src' })
20
+ * config({ src: 'src', minify: false })
21
+ * config({ minify: false }) // INVALID
22
+ */
23
+ export type EitherOrBoth<A, B, C = void, D = void> = C extends void
24
+ ? A | B | A & B
25
+ : (D extends void
26
+ ? A | B | C | A & B | A & C | B & C | A & B & C
27
+ : A | B | C | D |
28
+ A & B | A & C | A & D | B & C | B & D | C & D |
29
+ A & B & C | A & B & D | A & C & D | B & C & D |
30
+ A & B & C & D
31
+ )
32
+
33
+ /**
34
+ * `A` | `B` | `A & B`.
35
+ * Supports up to 4 types, and it is composable.
36
+ * This is useful when you want to compose multiple options together,
37
+ * while preserving their required field and structure.
38
+ * If the types overlaps each other, you may run into some corner cases.
39
+ * But in general usage it should work as expected.
40
+ * @deprecated renamed to `EitherOrBoth`
41
+ * @example
42
+ * type A = { src: string, minify?: boolean }
43
+ * type B = { logLevel: number }
44
+ * function config(options: EitherAnd<A, B>) { }
45
+ *
46
+ * config({ logLevel: 1 })
47
+ * config({ src: 'src' })
48
+ * config({ src: 'src', minify: false })
49
+ * config({ minify: false }) // INVALID
50
+ */
51
+ export type EitherAnd<A, B, C = void, D = void> = EitherOrBoth<A, B, C, D>