type-plus 7.2.1 → 7.3.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.
Files changed (59) hide show
  1. package/README.md +3 -0
  2. package/cjs/array/array.some.d.ts +1 -1
  3. package/cjs/merge.d.ts +55 -0
  4. package/cjs/merge.d.ts.map +1 -0
  5. package/cjs/merge.js +18 -0
  6. package/cjs/merge.js.map +1 -0
  7. package/cjs/mix_types/any_or_never_type.d.ts +18 -10
  8. package/cjs/mix_types/any_or_never_type.d.ts.map +1 -1
  9. package/cjs/object/AnyRecord.d.ts +2 -1
  10. package/cjs/object/AnyRecord.d.ts.map +1 -1
  11. package/cjs/object/index.d.ts +1 -0
  12. package/cjs/object/index.d.ts.map +1 -1
  13. package/cjs/object/index.js.map +1 -1
  14. package/cjs/object/left_join.d.ts +10 -38
  15. package/cjs/object/left_join.d.ts.map +1 -1
  16. package/cjs/object/left_join.js +0 -15
  17. package/cjs/object/left_join.js.map +1 -1
  18. package/cjs/object/optional_key.d.ts +35 -0
  19. package/cjs/object/optional_key.d.ts.map +1 -0
  20. package/cjs/object/optional_key.js +3 -0
  21. package/cjs/object/optional_key.js.map +1 -0
  22. package/cjs/testing/test_type.d.ts +36 -8
  23. package/cjs/testing/test_type.d.ts.map +1 -1
  24. package/cjs/testing/test_type.js.map +1 -1
  25. package/esm/array/array.some.d.ts +1 -1
  26. package/esm/merge.d.ts +55 -0
  27. package/esm/merge.d.ts.map +1 -0
  28. package/esm/merge.js +14 -0
  29. package/esm/merge.js.map +1 -0
  30. package/esm/mix_types/any_or_never_type.d.ts +18 -10
  31. package/esm/mix_types/any_or_never_type.d.ts.map +1 -1
  32. package/esm/object/AnyRecord.d.ts +2 -1
  33. package/esm/object/AnyRecord.d.ts.map +1 -1
  34. package/esm/object/index.d.ts +1 -0
  35. package/esm/object/index.d.ts.map +1 -1
  36. package/esm/object/index.js.map +1 -1
  37. package/esm/object/left_join.d.ts +10 -38
  38. package/esm/object/left_join.d.ts.map +1 -1
  39. package/esm/object/left_join.js +1 -13
  40. package/esm/object/left_join.js.map +1 -1
  41. package/esm/object/optional_key.d.ts +35 -0
  42. package/esm/object/optional_key.d.ts.map +1 -0
  43. package/esm/object/optional_key.js +2 -0
  44. package/esm/object/optional_key.js.map +1 -0
  45. package/esm/testing/test_type.d.ts +36 -8
  46. package/esm/testing/test_type.d.ts.map +1 -1
  47. package/esm/testing/test_type.js.map +1 -1
  48. package/package.json +4 -3
  49. package/ts/any/readme.md +20 -3
  50. package/ts/array/array.some.ts +1 -1
  51. package/ts/merge.ts +72 -0
  52. package/ts/mix_types/any_or_never_type.ts +18 -10
  53. package/ts/mix_types/readme.md +34 -0
  54. package/ts/object/AnyRecord.ts +3 -1
  55. package/ts/object/index.ts +1 -1
  56. package/ts/object/left_join.ts +15 -38
  57. package/ts/object/optional_key.ts +38 -0
  58. package/ts/object/readme.md +37 -0
  59. package/ts/testing/test_type.ts +37 -8
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/object/index.ts"],"names":[],"mappings":"AAiBA,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,oBAAoB,CAAA;AAClC,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AAEzB,cAAc,aAAa,CAAA;AAE3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,sBAAsB,CAAA;AACpC,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,+BAA+B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/object/index.ts"],"names":[],"mappings":"AAkBA,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,oBAAoB,CAAA;AAClC,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AAEzB,cAAc,aAAa,CAAA;AAE3B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,sBAAsB,CAAA;AACpC,cAAc,cAAc,CAAA;AAC5B,cAAc,YAAY,CAAA;AAC1B,cAAc,+BAA+B,CAAA"}
@@ -1,43 +1,15 @@
1
- import type { IsLiteral } from '../predicates/index.js';
1
+ import type { IsEqual } from '../equal/equal.js';
2
2
  import type { AnyRecord } from './AnyRecord.js';
3
3
  import type { IsDisjoint } from './IsDisjoint.js';
4
- import type { KeyTypes } from './KeyTypes.js';
5
- /**
6
- * Left join type `A` with type `B`.
7
- *
8
- * It handles cases like A or B are `Record`,
9
- * joining between required and optional props, etc.
10
- */
11
- export type LeftJoin<A extends AnyRecord, B extends AnyRecord> = IsDisjoint<A, B> extends true ? A & B : [keyof A, keyof B] extends [infer KA extends KeyTypes, infer KB extends KeyTypes] ? IsLiteral<KA> extends true ? IsLiteral<KB> extends true ? {
12
- [k in Exclude<KA, KB>]: A[k];
13
- } & {
14
- [k in KB]: undefined extends B[k] ? Exclude<A[k] | B[k], undefined> : B[k];
15
- } : {
16
- [k in Exclude<KA, KA & KB>]: A[k];
17
- } & {
18
- [k in Exclude<KB, KA & KB>]: B[k];
19
- } & {
20
- [k in KA & KB]: A[k] | B[k];
21
- } : IsLiteral<KB> extends true ? {
22
- [k in Exclude<KA, KB>]: A[k];
4
+ import type { KeysWithDiffType } from './KeysWithDiffType.js';
5
+ import type { Properties } from './properties.js';
6
+ export type ANotB<A extends AnyRecord, B extends AnyRecord> = IsEqual<A, B> extends true ? never : IsDisjoint<A, B> extends true ? A : {
7
+ [k in Exclude<keyof A, keyof B> | KeysWithDiffType<A, B>]: A[k];
8
+ };
9
+ export type BNotA<A extends AnyRecord, B extends AnyRecord> = ANotB<B, A>;
10
+ export type LeftJoin<A extends AnyRecord, B extends AnyRecord> = IsEqual<A, B> extends true ? A : IsDisjoint<A, B> extends true ? A & B : Properties<{
11
+ [k in Exclude<keyof A, keyof B>]: A[k];
23
12
  } & {
24
13
  [k in keyof B]: B[k];
25
- } : {
26
- [k in Exclude<KA, KA & KB>]: A[k];
27
- } & {
28
- [k in Exclude<KB, KA & KB>]: B[k];
29
- } & {
30
- [k in KA & KB]: A[k] | B[k];
31
- } : never;
32
- /**
33
- * Left join `a` with `b`.
34
- *
35
- * This returns the proper type of `{ ...a, ...b }`
36
- *
37
- * @example
38
- * ```ts
39
- * leftJoin({ a: 1 }, {} as { a?: string | undefined }) // { a: number | string }
40
- * ```
41
- */
42
- export declare function leftJoin<A extends AnyRecord, B extends AnyRecord>(a: A, b: B): LeftJoin<A, B>;
14
+ }>;
43
15
  //# sourceMappingURL=left_join.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"left_join.d.ts","sourceRoot":"","sources":["../../ts/object/left_join.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,SAAS,IAAI,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,IAAI,GAC3F,CAAC,GAAG,CAAC,GACL,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,QAAQ,EAAE,MAAM,EAAE,SAAS,QAAQ,CAAC,GACjF,SAAS,CAAC,EAAE,CAAC,SAAS,IAAI,GACzB,SAAS,CAAC,EAAE,CAAC,SAAS,IAAI,GACzB;KAAG,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG;KAClC,CAAC,IAAI,EAAE,GAAG,SAAS,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACzE,GACD;KAAG,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG;KAAG,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG;KAC/E,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC1B,GACF,SAAS,CAAC,EAAE,CAAC,SAAS,IAAI,GAC1B;KAAG,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAC3D;KAAG,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG;KAAG,CAAC,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG;KAC/E,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAC1B,GACF,KAAK,CAAA;AAER;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAE7F"}
1
+ {"version":3,"file":"left_join.d.ts","sourceRoot":"","sources":["../../ts/object/left_join.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,SAAS,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,IAAI,GACrF,KAAK,GACL,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,IAAI,GAC7B,CAAC,GACD;KAAG,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,CAAA;AAEtE,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,SAAS,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAEzE,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,SAAS,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,IAAI,GACxF,CAAC,GACD,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,IAAI,GAC7B,CAAC,GAAG,CAAC,GACL,UAAU,CAAC;KAAG,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC,CAAA"}
@@ -1,14 +1,2 @@
1
- /**
2
- * Left join `a` with `b`.
3
- *
4
- * This returns the proper type of `{ ...a, ...b }`
5
- *
6
- * @example
7
- * ```ts
8
- * leftJoin({ a: 1 }, {} as { a?: string | undefined }) // { a: number | string }
9
- * ```
10
- */
11
- export function leftJoin(a, b) {
12
- return { ...a, ...b };
13
- }
1
+ export {};
14
2
  //# sourceMappingURL=left_join.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"left_join.js","sourceRoot":"","sources":["../../ts/object/left_join.ts"],"names":[],"mappings":"AA6BA;;;;;;;;;GASG;AACH,MAAM,UAAU,QAAQ,CAA2C,CAAI,EAAE,CAAI;IAC5E,OAAO,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,EAAS,CAAA;AAC7B,CAAC"}
1
+ {"version":3,"file":"left_join.js","sourceRoot":"","sources":["../../ts/object/left_join.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import type { AnyRecord } from './AnyRecord.js';
2
+ import type { KeyTypes } from './KeyTypes.js';
3
+ /**
4
+ * Validate if the key `K` in `T` is optional.
5
+ *
6
+ * 🎭 *validate*
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * IsOptionalKey({ a: 1 }, 'a') // false
11
+ * IsOptionalKey({ a?: 1 }, 'a') // true
12
+ * ```
13
+ */
14
+ export type IsOptionalKey<T, K, Then = true, Else = false> = K extends OptionalKeys<T> ? Then : Else;
15
+ /**
16
+ * Gets the optional keys of `T`.
17
+ *
18
+ * 🦴 *utilities*
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * OptionalKeys<{ a: 1 }> // never
23
+ * OptionalKeys<{ a?: 1, b: number }> // 'a'
24
+ * ```
25
+ */
26
+ export type OptionalKeys<T> = T extends unknown ? {
27
+ [k in keyof T]-?: Record<KeyTypes, any> extends Pick<T, k> ? k : never;
28
+ }[keyof T] : never;
29
+ /**
30
+ * Parse `T` to keep only the optional properties.
31
+ */
32
+ export type OptionalProps<T extends AnyRecord> = T extends unknown ? {
33
+ [k in OptionalKeys<T>]?: T[k];
34
+ } : never;
35
+ //# sourceMappingURL=optional_key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optional_key.d.ts","sourceRoot":"","sources":["../../ts/object/optional_key.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,IAAI,GAAG,KAAK,IAAI,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA;AAEpG;;;;;;;;;;GAUG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,SAAS,OAAO,GAC5C;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAAE,CAAC,MAAM,CAAC,CAAC,GACnF,KAAK,CAAA;AAER;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,SAAS,OAAO,GAC/D;KAAG,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;CAAE,GACjC,KAAK,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=optional_key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optional_key.js","sourceRoot":"","sources":["../../ts/object/optional_key.ts"],"names":[],"mappings":""}
@@ -209,22 +209,27 @@ interface TestType {
209
209
  /**
210
210
  * A quick way to inspect a type.
211
211
  *
212
- * The handler is not being call.
212
+ * The handler receives a `InspectedType` object.
213
+ * It contains `value` which is typed to `T`,
214
+ * and many other properties to inspect the behavior of `T`.
213
215
  *
214
- * It just make it easy to inspect a specific type.
216
+ * The handler is not being call,
217
+ * it is use to hold the type in value for inspection.
218
+ *
219
+ * 🧪 *testing*
220
+ * 🦴 *utilities*
215
221
  *
216
222
  * @example
217
223
  * ```ts
218
- * testType.inspect<SomeType>(t => ...try out the `t` which is `SomeType` here...)
219
- *
220
- * // instead of
221
- * const r: SomeType = {} as any
222
- * ...try out the `r` which is `SomeType` here...
224
+ * testType.inspect<SomeType>(t => {
225
+ * type T = typeof t.value // resolve and inspect the type `T`
226
+ * t.extend_boolean // result of `T extends boolean`
227
+ * })
223
228
  * ```
224
229
  *
225
230
  * After trying out the type, remove the line.
226
231
  */
227
- inspect<T>(handler: (t: T) => unknown): (t: T) => unknown;
232
+ inspect<T>(handler: (t: InspectedType<T>) => unknown): T;
228
233
  }
229
234
  /**
230
235
  * Test utilities for types.
@@ -234,5 +239,28 @@ interface TestType {
234
239
  * so that the type can be further inspected.
235
240
  */
236
241
  export declare const testType: TestType;
242
+ export type InspectedType<T> = {
243
+ value: T;
244
+ extends_any: T extends any ? true : false;
245
+ extends_unknown: T extends unknown ? true : false;
246
+ extends_void: T extends void ? true : false;
247
+ extends_never: T extends never ? true : false;
248
+ extends_undefined: T extends undefined ? true : false;
249
+ extends_null: T extends null ? true : false;
250
+ extends_boolean: T extends boolean ? true : false;
251
+ extends_true: T extends true ? true : false;
252
+ extends_false: T extends false ? true : false;
253
+ extends_number: T extends number ? true : false;
254
+ extends_1: T extends 1 ? true : false;
255
+ extends_bigint: T extends bigint ? true : false;
256
+ extends_1n: T extends 1n ? true : false;
257
+ extends_string: T extends string ? true : false;
258
+ extends_a: T extends 'a' ? true : false;
259
+ extends_symbol: T extends symbol ? true : false;
260
+ extends_object: T extends object ? true : false;
261
+ extends_function: T extends Function ? true : false;
262
+ extends_array_unknown: T extends unknown[] ? true : false;
263
+ extends_tuple_empty: T extends [] ? true : false;
264
+ };
237
265
  export {};
238
266
  //# sourceMappingURL=test_type.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"test_type.d.ts","sourceRoot":"","sources":["../../ts/testing/test_type.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test_type.d.ts","sourceRoot":"","sources":["../../ts/testing/test_type.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"test_type.js","sourceRoot":"","sources":["../../ts/testing/test_type.ts"],"names":[],"mappings":"AAuOA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,EAAc,EAAE;IACjD,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS;QAC5B,OAAO,CAAC,QAAiB,EAAE,EAAE,CAAC,QAAQ,CAAA;IACvC,CAAC;CACD,CAAC,CAAA"}
1
+ {"version":3,"file":"test_type.js","sourceRoot":"","sources":["../../ts/testing/test_type.ts"],"names":[],"mappings":"AA4OA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,EAAc,EAAE;IACjD,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS;QAC5B,OAAO,CAAC,QAAiB,EAAE,EAAE,CAAC,QAAQ,CAAA;IACvC,CAAC;CACD,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "type-plus",
3
- "version": "7.2.1",
3
+ "version": "7.3.1",
4
4
  "description": "Provides additional types for TypeScript.",
5
- "homepage": "https://github.com/unional/type-plus/tree/main/type-plus",
5
+ "homepage": "https://github.com/unional/type-plus/tree/main/type-plus#readme",
6
6
  "bugs": {
7
7
  "url": "https://github.com/unional/type-plus/issues"
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "https://github.com/unional/type-plus.git"
11
+ "url": "https://github.com/unional/type-plus.git",
12
+ "directory": "type-plus"
12
13
  },
13
14
  "license": "MIT",
14
15
  "author": {
package/ts/any/readme.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Any
2
2
 
3
- `any` is one of the two top type in TypeScript. It is the supertype of all types. It is a way to opt-out of type checking and let the values pass through compile-time checks.
3
+ `any` is one of the two top types in TypeScript.
4
+ It is a supertype of all types.
5
+ It is a way to opt-out of type checking and let the values pass through compile-time checks.
4
6
 
5
7
  ## Type Checking
6
8
 
@@ -15,9 +17,24 @@ except `any & never` which is `never`.
15
17
  - [`NotAnyType<T, Then = T, Else = never>`](any_type.ts#L45): check if `T` is not exactly `any`.
16
18
  - [`IsNotAny<T, Then = true, Else = false>`](any_type.ts#L60): is `T` not exactly `any`.
17
19
 
18
- ## Type Utilities
20
+ ## Trivia
19
21
 
20
- - [`IsAnyOrNever<T, Then = true, Else = false>`](any_or_never.ts#L17)]: is `T` type `any` or `never`.
22
+ > Both `any` and `unknown` are top types?
23
+
24
+ Well, yeah:
25
+
26
+ ```ts
27
+ type A = any extends unknown ? 1 : 2 // 1
28
+ type B = unknown extends any ? 1 : 2 // 1
29
+ ```
30
+
31
+ > Aren't using `any` is bad?
32
+
33
+ If you use it to simply tell TypeScript to shut up because you are lazy, then yes.
34
+
35
+ But it is ok to use `any` in many cases, as the type system of TypeScript is not sounded.
36
+
37
+ There are many cases it is not possible to induce the type correctly.
21
38
 
22
39
  ## References
23
40
 
@@ -11,7 +11,7 @@ import type { UnionOfValues } from './union_of_values.js'
11
11
  *
12
12
  * You can also change it to `strict` mode.
13
13
  *
14
- * 🔧 *utilities*
14
+ * 🦴 *utilities*
15
15
  *
16
16
  * @example
17
17
  * ```ts
package/ts/merge.ts ADDED
@@ -0,0 +1,72 @@
1
+ import type { NonComposableTypes } from './composable_types.js'
2
+ import type { AnyRecord } from './object/AnyRecord.js'
3
+ import type { IsDisjoint } from './object/IsDisjoint.js'
4
+ import type { KeyTypes } from './object/KeyTypes.js'
5
+ import type { OptionalKeys } from './object/OptionalKeys.js'
6
+ import type { Properties } from './object/properties.js'
7
+ import type { IsLiteral } from './predicates/literal.js'
8
+
9
+ /**
10
+ * Left join type `A` with type `B`.
11
+ *
12
+ * It handles cases like A or B are `Record`,
13
+ * joining between required and optional props, etc.
14
+ */
15
+ export type Merge<A, B> = [A, B] extends [NonComposableTypes, unknown] ? B
16
+ : [A, B] extends [unknown, NonComposableTypes] ? A
17
+ : A extends AnyRecord ? B extends AnyRecord
18
+ ? IsDisjoint<A, B> extends true
19
+ ? A & B
20
+ : ([keyof A, keyof B] extends [infer KA extends KeyTypes, infer KB extends KeyTypes]
21
+ ? (IsLiteral<KA> extends true
22
+ ? (IsLiteral<KB> extends true
23
+ ? ([OptionalKeys<A>, OptionalKeys<B>] extends [infer PKA extends KeyTypes, infer PKB extends KeyTypes]
24
+ ?
25
+ // property is optional when both A[k] and B[k] are optional
26
+ {
27
+ [k in PKA & PKB]?: A[k] | B[k] | undefined
28
+ } &
29
+ {
30
+ [k in Exclude<KA & KB, PKA | PKB>]: Merge.JoinProps<A[k], B[k]>
31
+ } &
32
+ // properties only in A excluding partials is A[k]
33
+ { [k in Exclude<KA, PKA | KB>]: A[k] } &
34
+ // properties only in B excluding partials is B[k]
35
+ { [k in Exclude<KB, PKB>]: B[k] } &
36
+ // properties is required in A but optional in B is unionized without undefined
37
+ { [k in Exclude<KA & PKB, PKA>]: Exclude<A[k] | Partial<B[k]>, undefined> }
38
+ : never)
39
+ : Properties<
40
+ { [k in Exclude<KA, KA & KB>]: A[k] } &
41
+ { [k in Exclude<KB, KA & KB>]: B[k] } &
42
+ { [k in KA & KB]: A[k] | B[k] }
43
+ >)
44
+ : (IsLiteral<KB> extends true
45
+ ? { [k in Exclude<KA, KB>]: A[k] } & { [k in keyof B]: B[k] }
46
+ : { [k in Exclude<KA, KA & KB>]: A[k] } & { [k in Exclude<KB, KA & KB>]: B[k] } & {
47
+ [k in KA & KB]: A[k] | B[k]
48
+ }))
49
+ : never)
50
+ : never : never
51
+
52
+ export namespace Merge {
53
+ export type JoinProps<A, B> = A extends NonComposableTypes
54
+ ? B
55
+ : (B extends NonComposableTypes
56
+ ? A
57
+ : A & B)
58
+ }
59
+
60
+ /**
61
+ * Left join `a` with `b`.
62
+ *
63
+ * This returns the proper type of `{ ...a, ...b }`
64
+ *
65
+ * @example
66
+ * ```ts
67
+ * leftJoin({ a: 1 }, {} as { a?: string | undefined }) // { a: number | string }
68
+ * ```
69
+ */
70
+ export function merge<A, B>(a: A, b: B): Merge<A, B> {
71
+ return { ...a, ...b } as any
72
+ }
@@ -1,22 +1,30 @@
1
- import type { IsNever } from '../never/never_type.js'
2
- import type { IsAny } from '../any/any_type.js'
1
+ import type { AnyType } from '../any/any_type.js'
2
+ import type { NeverType } from '../never/never_type.js'
3
3
 
4
4
  /**
5
- * 🐾 Parse `T` to ensure it is either exactly `any` or exactly `never`.
5
+ * Parse `T` to ensure it is either exactly `any` or exactly `never`.
6
+ *
7
+ * 🐾 *parse*
8
+ * 🩳 *shortcut*
6
9
  *
7
10
  * @example
8
11
  * ```ts
9
- * type R = AnyType<any> // any
12
+ * type R = AnyOrNeverType<any> // any
13
+ * type R = AnyOrNeverType<never> // never
14
+ * type R = AnyOrNeverType<never, 1, 2> // 1
10
15
  *
11
- * type R = AnyType<never> // never
12
- * type R = AnyType<unknown> // never
13
- * type R = AnyType<string | boolean> // never
16
+ * type R = AnyOrNeverType<unknown> // never
17
+ * type R = AnyOrNeverType<unknown, 1, 2> // 2
18
+ * type R = AnyOrNeverType<string | boolean> // never
14
19
  * ```
15
20
  */
16
- export type AnyOrNeverType<T, Then = T, Else = never> = IsNever<T, Then, IsAny<T, Then, Else>>
21
+ export type AnyOrNeverType<T, Then = T, Else = never> = NeverType<T, Then, AnyType<T, Then, Else>>
17
22
 
18
23
  /**
19
- * 🎭 Validate if `T` is either exactly `any` or exactly `never`.
24
+ * Validate if `T` is either exactly `any` or exactly `never`.
25
+ *
26
+ * 🎭 *validate*
27
+ * 🩳 *shortcut*
20
28
  *
21
29
  * @example
22
30
  * ```ts
@@ -27,4 +35,4 @@ export type AnyOrNeverType<T, Then = T, Else = never> = IsNever<T, Then, IsAny<T
27
35
  * type R = IsAnyOrNever<unknown> // false
28
36
  * ```
29
37
  */
30
- export type IsAnyOrNever<T, Then = true, Else = false> = IsNever<T, Then, IsAny<T, Then, Else>>
38
+ export type IsAnyOrNever<T, Then = true, Else = false> = NeverType<T, Then, AnyType<T, Then, Else>>
@@ -0,0 +1,34 @@
1
+ # Mix Types
2
+
3
+ This folder contains types and utilities that work across multiple types.
4
+
5
+ ## [AnyOrNeverType](./any_or_never_type.ts)
6
+
7
+ `AnyOrNeverType<T, Then = T, Else = never>` 🎭 🩳
8
+
9
+ Parse `T` to ensure it is either exactly `any` or exactly `never`.
10
+
11
+ ```ts
12
+ import type { AnyOrNeverType } from 'type-plus'
13
+
14
+ type R = AnyOrNeverType<any> // any
15
+ type R = AnyOrNeverType<never> // never
16
+ type R = AnyOrNeverType<never, 1, 2> // 1
17
+
18
+ type R = AnyOrNeverType<unknown, 1, 2> // 2
19
+ ```
20
+
21
+ ## [IsAnyOrNever](./any_or_never_type.ts)
22
+
23
+ `IsAnyOrNever<T, Then = true, Else = false>` 🎭 🩳
24
+
25
+ Validate if `T` is either exactly `any` or exactly `never`.
26
+
27
+ ```ts
28
+ import type { IsAnyOrNever } from 'type-plus'
29
+
30
+ type R = IsAnyOrNever<any> // true
31
+ type R = IsAnyOrNever<never> // true
32
+
33
+ type R = IsAnyOrNever<unknown> // false
34
+ ```
@@ -1 +1,3 @@
1
- export type AnyRecord = Record<keyof any, any>
1
+ import type { KeyTypes } from './KeyTypes.js'
2
+
3
+ export type AnyRecord = Record<KeyTypes, any>
@@ -9,6 +9,7 @@ export type { KeysWithDiffType } from './KeysWithDiffType.js'
9
9
  export type { KnownKeys } from './KnownKeys.js'
10
10
  export type { OptionalKeys } from './OptionalKeys.js'
11
11
  export type { Partial, PartialExcept, PartialOmit, PartialPick } from './Partial.js'
12
+ export type * from './optional_key.js'
12
13
  export type { RecursiveIntersect } from './RecursiveIntersect.js'
13
14
  export type { RecursiveRequired } from './RecursiveRequired.js'
14
15
  export type { RequiredExcept, RequiredPick } from './Required.js'
@@ -36,4 +37,3 @@ export * from './replaceProperty.js'
36
37
  export * from './someKey.js'
37
38
  export * from './split.js'
38
39
  export * from './typeOverrideIncompatible.js'
39
-
@@ -1,42 +1,19 @@
1
- import type { IsLiteral } from '../predicates/index.js'
1
+ import type { IsEqual } from '../equal/equal.js'
2
2
  import type { AnyRecord } from './AnyRecord.js'
3
3
  import type { IsDisjoint } from './IsDisjoint.js'
4
- import type { KeyTypes } from './KeyTypes.js'
4
+ import type { KeysWithDiffType } from './KeysWithDiffType.js'
5
+ import type { Properties } from './properties.js'
5
6
 
6
- /**
7
- * Left join type `A` with type `B`.
8
- *
9
- * It handles cases like A or B are `Record`,
10
- * joining between required and optional props, etc.
11
- */
12
- export type LeftJoin<A extends AnyRecord, B extends AnyRecord> = IsDisjoint<A, B> extends true
13
- ? A & B
14
- : [keyof A, keyof B] extends [infer KA extends KeyTypes, infer KB extends KeyTypes]
15
- ? IsLiteral<KA> extends true
16
- ? IsLiteral<KB> extends true
17
- ? { [k in Exclude<KA, KB>]: A[k] } & {
18
- [k in KB]: undefined extends B[k] ? Exclude<A[k] | B[k], undefined> : B[k]
19
- }
20
- : { [k in Exclude<KA, KA & KB>]: A[k] } & { [k in Exclude<KB, KA & KB>]: B[k] } & {
21
- [k in KA & KB]: A[k] | B[k]
22
- }
23
- : IsLiteral<KB> extends true
24
- ? { [k in Exclude<KA, KB>]: A[k] } & { [k in keyof B]: B[k] }
25
- : { [k in Exclude<KA, KA & KB>]: A[k] } & { [k in Exclude<KB, KA & KB>]: B[k] } & {
26
- [k in KA & KB]: A[k] | B[k]
27
- }
28
- : never
7
+ export type ANotB<A extends AnyRecord, B extends AnyRecord> = IsEqual<A, B> extends true
8
+ ? never
9
+ : IsDisjoint<A, B> extends true
10
+ ? A
11
+ : { [k in Exclude<keyof A, keyof B> | KeysWithDiffType<A, B>]: A[k] }
12
+
13
+ export type BNotA<A extends AnyRecord, B extends AnyRecord> = ANotB<B, A>
29
14
 
30
- /**
31
- * Left join `a` with `b`.
32
- *
33
- * This returns the proper type of `{ ...a, ...b }`
34
- *
35
- * @example
36
- * ```ts
37
- * leftJoin({ a: 1 }, {} as { a?: string | undefined }) // { a: number | string }
38
- * ```
39
- */
40
- export function leftJoin<A extends AnyRecord, B extends AnyRecord>(a: A, b: B): LeftJoin<A, B> {
41
- return { ...a, ...b } as any
42
- }
15
+ export type LeftJoin<A extends AnyRecord, B extends AnyRecord> = IsEqual<A, B> extends true
16
+ ? A
17
+ : IsDisjoint<A, B> extends true
18
+ ? A & B
19
+ : Properties<{ [k in Exclude<keyof A, keyof B>]: A[k] } & { [k in keyof B]: B[k] }>
@@ -0,0 +1,38 @@
1
+
2
+ import type { AnyRecord } from './AnyRecord.js'
3
+ import type { KeyTypes } from './KeyTypes.js'
4
+
5
+ /**
6
+ * Validate if the key `K` in `T` is optional.
7
+ *
8
+ * 🎭 *validate*
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * IsOptionalKey({ a: 1 }, 'a') // false
13
+ * IsOptionalKey({ a?: 1 }, 'a') // true
14
+ * ```
15
+ */
16
+ export type IsOptionalKey<T, K, Then = true, Else = false> = K extends OptionalKeys<T> ? Then : Else
17
+
18
+ /**
19
+ * Gets the optional keys of `T`.
20
+ *
21
+ * 🦴 *utilities*
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * OptionalKeys<{ a: 1 }> // never
26
+ * OptionalKeys<{ a?: 1, b: number }> // 'a'
27
+ * ```
28
+ */
29
+ export type OptionalKeys<T> = T extends unknown
30
+ ? { [k in keyof T]-?: Record<KeyTypes, any> extends Pick<T, k> ? k : never }[keyof T]
31
+ : never
32
+
33
+ /**
34
+ * Parse `T` to keep only the optional properties.
35
+ */
36
+ export type OptionalProps<T extends AnyRecord> = T extends unknown
37
+ ? { [k in OptionalKeys<T>]?: T[k] }
38
+ : never
@@ -21,6 +21,43 @@ type R = ObjectType<1> // never
21
21
  - [`NotObjectType<T, Then = T, Else = never>`](object_type.ts#L48): check if `T` is not `object`.
22
22
  - [`IsNotObject<T, Then = true, Else = false>`](object_type.ts#L65): is `T` not `object`.
23
23
 
24
+ ## IsOptionalKey
25
+
26
+ > `IsOptionalKey<T, K, Then = true, Else = false>`
27
+
28
+ Validate if the key `K` in `T` is optional.
29
+
30
+ ```ts
31
+ import type { IsOptionalKey } from 'type-plus'
32
+
33
+ type R = IsOptionalKey<{ a?: number }, 'a'> // true
34
+ type R = IsOptionalKey<{ a: number }, 'a'> // false
35
+ ```
36
+
37
+ ## OptionalKeys
38
+
39
+ > `OptionalKeys<T>`
40
+
41
+ Gets the optional keys of `T`.
42
+
43
+ ```ts
44
+ import type { OptionalKeys } from 'type-plus'
45
+
46
+ type R = OptionalKeys<{ a?: number; b: string }> // 'a'
47
+ ```
48
+
49
+ ## OptionalProps
50
+
51
+ > `OptionalProps<T>`
52
+
53
+ Gets the optional properties of `T`.
54
+
55
+ ```ts
56
+ import type { OptionalProps } from 'type-plus'
57
+
58
+ type R = OptionalProps<{ a?: number; b: string }> // { a?: number }
59
+ ```
60
+
24
61
  ## References
25
62
 
26
63
  - [Handbook]