@kakasoo/deep-strict-types 2.0.4 → 2.0.5
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/bin/src/types/ElementOf.d.ts +28 -1
- package/bin/src/types/ElementOf.d.ts.map +1 -1
- package/bin/src/types/Equal.d.ts +28 -2
- package/bin/src/types/Equal.d.ts.map +1 -1
- package/bin/src/types/GetType.d.ts +35 -13
- package/bin/src/types/GetType.d.ts.map +1 -1
- package/bin/src/types/IsUnion.d.ts +26 -6
- package/bin/src/types/IsUnion.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @title Type for Inferring the Element Type of an Array.
|
|
3
|
+
*
|
|
4
|
+
* Extracts the element type from an array type. This utility type uses conditional types
|
|
5
|
+
* with the `infer` keyword to extract the type of elements contained within an array.
|
|
6
|
+
*
|
|
7
|
+
* @template T - The array type from which to extract the element type
|
|
8
|
+
* @returns The type of elements in the array, or `never` if T is not an array
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* type StringArray = string[];
|
|
13
|
+
* type StringElement = ElementOf<StringArray>; // string
|
|
14
|
+
*
|
|
15
|
+
* type NumberArray = number[];
|
|
16
|
+
* type NumberElement = ElementOf<NumberArray>; // number
|
|
17
|
+
*
|
|
18
|
+
* type MixedArray = (string | number)[];
|
|
19
|
+
* type MixedElement = ElementOf<MixedArray>; // string | number
|
|
20
|
+
*
|
|
21
|
+
* type ObjectArray = { id: number; name: string }[];
|
|
22
|
+
* type ObjectElement = ElementOf<ObjectArray>; // { id: number; name: string }
|
|
23
|
+
*
|
|
24
|
+
* type ReadonlyArray = readonly string[];
|
|
25
|
+
* type ReadonlyElement = ElementOf<ReadonlyArray>; // string
|
|
26
|
+
*
|
|
27
|
+
* type TupleArray = [string, number, boolean];
|
|
28
|
+
* type TupleElement = ElementOf<TupleArray>; // string | number | boolean
|
|
29
|
+
* ```
|
|
3
30
|
*/
|
|
4
|
-
export type ElementOf<T extends
|
|
31
|
+
export type ElementOf<T extends any[] | readonly any[]> = T extends (infer E)[] ? E : T extends readonly (infer E)[] ? E : never;
|
|
5
32
|
//# sourceMappingURL=ElementOf.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElementOf.d.ts","sourceRoot":"","sources":["../../../src/types/ElementOf.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ElementOf.d.ts","sourceRoot":"","sources":["../../../src/types/ElementOf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,MAAM,SAAS,CAAC,CAAC,SAAS,GAAG,EAAE,GAAG,SAAS,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAC3E,CAAC,GACD,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAC5B,CAAC,GACD,KAAK,CAAC"}
|
package/bin/src/types/Equal.d.ts
CHANGED
|
@@ -1,13 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Helper type that creates a generic function signature for type comparison.
|
|
3
|
+
* This technique leverages TypeScript's strict function type checking to determine type equality.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
3
6
|
*/
|
|
4
7
|
type Expression<X> = <T>() => T extends X ? 1 : 2;
|
|
5
8
|
/**
|
|
6
9
|
* @title Type for Checking if Two Types are Equal.
|
|
7
10
|
*
|
|
8
11
|
* The `Equal<X, Y>` type uses conditional types and a helper type `Expression<X>`
|
|
9
|
-
* to determine if two types `X` and `Y` are the same. It returns `true` if they are
|
|
12
|
+
* to determine if two types `X` and `Y` are exactly the same. It returns `true` if they are
|
|
10
13
|
* equal, and `false` otherwise.
|
|
14
|
+
*
|
|
15
|
+
* This type performs a strict equality check that distinguishes between:
|
|
16
|
+
* - `any` vs other types
|
|
17
|
+
* - `unknown` vs other types
|
|
18
|
+
* - Union types with different members
|
|
19
|
+
* - Branded types vs their base types
|
|
20
|
+
*
|
|
21
|
+
* @template X - The first type to compare
|
|
22
|
+
* @template Y - The second type to compare
|
|
23
|
+
* @returns `true` if X and Y are exactly the same type, `false` otherwise
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* type Test1 = Equal<string, string>; // true
|
|
28
|
+
* type Test2 = Equal<string, number>; // false
|
|
29
|
+
* type Test3 = Equal<string | number, string | number>; // true
|
|
30
|
+
* type Test4 = Equal<string | number, number | string>; // true (order doesn't matter)
|
|
31
|
+
* type Test5 = Equal<{ a: string }, { a: string }>; // true
|
|
32
|
+
* type Test6 = Equal<{ a: string }, { a: string; b?: string }>; // false
|
|
33
|
+
* type Test7 = Equal<any, string>; // false
|
|
34
|
+
* type Test8 = Equal<unknown, any>; // false
|
|
35
|
+
* type Test9 = Equal<string & { __brand: 'ID' }, string>; // false (branded types)
|
|
36
|
+
* ```
|
|
11
37
|
*/
|
|
12
38
|
export type Equal<X, Y> = Expression<X> extends Expression<Y> ? true : false;
|
|
13
39
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Equal.d.ts","sourceRoot":"","sources":["../../../src/types/Equal.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"Equal.d.ts","sourceRoot":"","sources":["../../../src/types/Equal.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC"}
|
|
@@ -3,27 +3,49 @@ import type { DeepStrictObjectKeys } from './DeepStrictObjectKeys';
|
|
|
3
3
|
import type { ElementOf } from './ElementOf';
|
|
4
4
|
import type { RemoveArraySymbol } from './RemoveArraySymbol';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Helper type that extracts all value types from an object type.
|
|
7
|
+
* Similar to `T[keyof T]`, it returns a union of all property value types.
|
|
8
|
+
*
|
|
9
|
+
* @internal
|
|
10
|
+
* @template T - The object type to extract values from
|
|
7
11
|
*/
|
|
8
12
|
type ValueOf<T> = T[keyof T];
|
|
9
13
|
/**
|
|
10
|
-
* @title
|
|
14
|
+
* @title Type for extracting the type at a specific nested path in an object.
|
|
11
15
|
*
|
|
12
|
-
* This type extracts the type of a specific key from a nested object,
|
|
16
|
+
* This type extracts the type of a specific key from a nested object structure,
|
|
13
17
|
* supporting arrays and deeply nested keys. It uses `DeepStrictObjectKeys`
|
|
14
|
-
* to
|
|
18
|
+
* to validate the key path and correctly resolves the type for the given key.
|
|
19
|
+
*
|
|
20
|
+
* Key features:
|
|
21
|
+
* - Supports dot notation for nested object access (e.g., "a.b.c")
|
|
22
|
+
* - Handles array access with `[*]` notation (e.g., "items[*].name")
|
|
23
|
+
* - Type-safe: only accepts valid key paths as defined by `DeepStrictObjectKeys`
|
|
24
|
+
* - Recursively resolves nested types through objects and arrays
|
|
15
25
|
*
|
|
16
|
-
*
|
|
17
|
-
* -
|
|
18
|
-
*
|
|
26
|
+
* @template T - The object type to extract from
|
|
27
|
+
* @template K - The key path string (must be a valid key from DeepStrictObjectKeys<T>)
|
|
28
|
+
* @returns The type at the specified path, or `never` if the path is invalid
|
|
19
29
|
*
|
|
20
|
-
* @
|
|
21
|
-
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* type Data = {
|
|
33
|
+
* user: {
|
|
34
|
+
* name: string;
|
|
35
|
+
* posts: {
|
|
36
|
+
* title: string;
|
|
37
|
+
* tags: string[];
|
|
38
|
+
* }[];
|
|
39
|
+
* };
|
|
40
|
+
* };
|
|
22
41
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* type
|
|
26
|
-
* type
|
|
42
|
+
* type UserType = GetType<Data, "user">; // { name: string; posts: {...}[] }
|
|
43
|
+
* type NameType = GetType<Data, "user.name">; // string
|
|
44
|
+
* type PostsType = GetType<Data, "user.posts">; // { title: string; tags: string[] }[]
|
|
45
|
+
* type PostType = GetType<Data, "user.posts[*]">; // { title: string; tags: string[] }
|
|
46
|
+
* type TitleType = GetType<Data, "user.posts[*].title">; // string
|
|
47
|
+
* type TagsType = GetType<Data, "user.posts[*].tags">; // string[]
|
|
48
|
+
* type TagType = GetType<Data, "user.posts[*].tags[*]">; // string
|
|
27
49
|
* ```
|
|
28
50
|
*/
|
|
29
51
|
export type GetType<T extends object, K extends DeepStrictObjectKeys<T>> = StringType.Split<K, '.'> extends [infer First extends keyof T] ? ValueOf<Pick<T, First>> : StringType.Split<K, '.'> extends [infer First extends string, ...infer Rest extends string[]] ? RemoveArraySymbol<First> extends keyof T ? ValueOf<Pick<T, RemoveArraySymbol<First>>> extends object ? ValueOf<Pick<T, RemoveArraySymbol<First>>> extends Array<infer E> ? E extends object ? GetType<E, Extract<ArrayType.Join<Rest, '.'>, DeepStrictObjectKeys<E>>> : E : GetType<ValueOf<Pick<T, RemoveArraySymbol<First>>>, Extract<ArrayType.Join<Rest, '.'>, DeepStrictObjectKeys<ValueOf<Pick<T, RemoveArraySymbol<First>>>>>> : never : T extends any[] ? RemoveArraySymbol<First> extends '' ? GetType<ElementOf<T>, Extract<ArrayType.Join<Rest, '.'>, DeepStrictObjectKeys<ElementOf<T>>>> : never : never : never;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GetType.d.ts","sourceRoot":"","sources":["../../../src/types/GetType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D
|
|
1
|
+
{"version":3,"file":"GetType.d.ts","sourceRoot":"","sources":["../../../src/types/GetType.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;;;;;GAMG;AACH,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,oBAAoB,CAAC,CAAC,CAAC,IACrE,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,MAAM,KAAK,SAAS,MAAM,CAAC,CAAC,GAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GACvB,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,MAAM,KAAK,SAAS,MAAM,EAAE,GAAG,MAAM,IAAI,SAAS,MAAM,EAAE,CAAC,GAC3F,iBAAiB,CAAC,KAAK,CAAC,SAAS,MAAM,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,MAAM,GACvD,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GAC/D,CAAC,SAAS,MAAM,GACd,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,GACvE,CAAC,GACH,OAAO,CACL,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,EAC1C,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CACrG,GACH,KAAK,GACP,CAAC,SAAS,GAAG,EAAE,GACb,iBAAiB,CAAC,KAAK,CAAC,SAAS,EAAE,GACjC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAC7F,KAAK,GACP,KAAK,GACT,KAAK,CAAC"}
|
|
@@ -1,19 +1,39 @@
|
|
|
1
1
|
import type { Equal } from './Equal';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Helper type that checks if a partition of type T is the same as the entire type T.
|
|
4
|
+
* This works by distributing T through conditional types and checking if each partition
|
|
5
|
+
* equals the whole. For union types, this produces `false | true`, while for single types
|
|
6
|
+
* it produces just `false`.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
* @template T - The type to check
|
|
10
|
+
* @template P - The preserved original type (defaults to T)
|
|
4
11
|
*/
|
|
5
12
|
type IsPartitionSameEntire<T, P = T> = T extends any ? P extends T ? false : true : never;
|
|
6
13
|
/**
|
|
7
14
|
* @title Type for checking if a type is a union type.
|
|
8
15
|
*
|
|
9
|
-
* This type uses the `IsPartitionSameEntire` type to check whether the provided type `T` is a union type.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
16
|
+
* This type uses the `IsPartitionSameEntire` helper type to check whether the provided type `T` is a union type.
|
|
17
|
+
* It works by partitioning the type `T` and checking if the type consists of multiple distinct elements.
|
|
18
|
+
*
|
|
19
|
+
* The detection mechanism:
|
|
20
|
+
* - For union types: produces `boolean` (which is `false | true`)
|
|
21
|
+
* - For single types: produces `false`
|
|
22
|
+
* - Then checks if the result equals `boolean` to determine if it's a union
|
|
23
|
+
*
|
|
24
|
+
* @template T - The type to check
|
|
25
|
+
* @returns `true` if T is a union type, `false` otherwise
|
|
12
26
|
*
|
|
13
|
-
*
|
|
14
|
-
* ```
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
15
29
|
* type Test1 = IsUnion<string | number>; // true
|
|
16
30
|
* type Test2 = IsUnion<string>; // false
|
|
31
|
+
* type Test3 = IsUnion<'a' | 'b' | 'c'>; // true
|
|
32
|
+
* type Test4 = IsUnion<{ a: string } | { b: number }>; // true
|
|
33
|
+
* type Test5 = IsUnion<never>; // false
|
|
34
|
+
* type Test6 = IsUnion<unknown>; // false
|
|
35
|
+
* type Test7 = IsUnion<any>; // false
|
|
36
|
+
* type Test8 = IsUnion<boolean>; // true (boolean is true | false)
|
|
17
37
|
* ```
|
|
18
38
|
*/
|
|
19
39
|
export type IsUnion<T> = Equal<IsPartitionSameEntire<T>, boolean> extends true ? true : false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IsUnion.d.ts","sourceRoot":"","sources":["../../../src/types/IsUnion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC
|
|
1
|
+
{"version":3,"file":"IsUnion.d.ts","sourceRoot":"","sources":["../../../src/types/IsUnion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC;;;;;;;;;GASG;AACH,KAAK,qBAAqB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,GAChD,CAAC,SAAS,CAAC,GACT,KAAK,GACL,IAAI,GACN,KAAK,CAAC;AAEV;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC"}
|