type-fest 4.13.0 → 4.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/index.d.ts +1 -0
- package/package.json +17 -4
- package/readme.md +1 -0
- package/source/asyncify.d.ts +1 -1
- package/source/distributed-pick.d.ts +85 -0
- package/source/internal.d.ts +1 -1
- package/source/readonly-deep.d.ts +1 -1
- package/source/set-parameter-type.d.ts +11 -8
- package/source/set-return-type.d.ts +4 -4
- package/source/tsconfig-json.d.ts +1 -0
package/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './source/observable-like';
|
|
|
7
7
|
// Utilities
|
|
8
8
|
export type {KeysOfUnion} from './source/keys-of-union';
|
|
9
9
|
export type {DistributedOmit} from './source/distributed-omit';
|
|
10
|
+
export type {DistributedPick} from './source/distributed-pick';
|
|
10
11
|
export type {EmptyObject, IsEmptyObject} from './source/empty-object';
|
|
11
12
|
export type {NonEmptyObject} from './source/non-empty-object';
|
|
12
13
|
export type {UnknownRecord} from './source/unknown-record';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "type-fest",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.14.0",
|
|
4
4
|
"description": "A collection of essential TypeScript types",
|
|
5
5
|
"license": "(MIT OR CC0-1.0)",
|
|
6
6
|
"repository": "sindresorhus/type-fest",
|
|
@@ -16,7 +16,12 @@
|
|
|
16
16
|
"node": ">=16"
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
|
-
"test": "
|
|
19
|
+
"test:set-parameter-type": "tsc --noEmit test-d/set-parameter-type",
|
|
20
|
+
"test:source-files-extension": "node script/test/source-files-extension.js",
|
|
21
|
+
"test:tsc": "tsc",
|
|
22
|
+
"test:tsd": "tsd",
|
|
23
|
+
"test:xo": "xo",
|
|
24
|
+
"test": "run-p test:*"
|
|
20
25
|
},
|
|
21
26
|
"files": [
|
|
22
27
|
"index.d.ts",
|
|
@@ -37,9 +42,10 @@
|
|
|
37
42
|
"devDependencies": {
|
|
38
43
|
"@sindresorhus/tsconfig": "~0.7.0",
|
|
39
44
|
"expect-type": "^0.15.0",
|
|
45
|
+
"npm-run-all2": "^6.1.2",
|
|
40
46
|
"tsd": "^0.28.1",
|
|
41
47
|
"typescript": "^5.2.2",
|
|
42
|
-
"xo": "^0.
|
|
48
|
+
"xo": "^0.58.0"
|
|
43
49
|
},
|
|
44
50
|
"xo": {
|
|
45
51
|
"rules": {
|
|
@@ -49,7 +55,14 @@
|
|
|
49
55
|
"import/extensions": "off",
|
|
50
56
|
"@typescript-eslint/no-redeclare": "off",
|
|
51
57
|
"@typescript-eslint/no-confusing-void-expression": "off",
|
|
52
|
-
"@typescript-eslint/no-unsafe-argument": "off"
|
|
58
|
+
"@typescript-eslint/no-unsafe-argument": "off",
|
|
59
|
+
"object-curly-newline": [
|
|
60
|
+
"error",
|
|
61
|
+
{
|
|
62
|
+
"multiline": true,
|
|
63
|
+
"consistent": true
|
|
64
|
+
}
|
|
65
|
+
]
|
|
53
66
|
}
|
|
54
67
|
},
|
|
55
68
|
"tsd": {
|
package/readme.md
CHANGED
|
@@ -183,6 +183,7 @@ Click the type names for complete docs.
|
|
|
183
183
|
- [`Paths`](source/paths.d.ts) - Generate a union of all possible paths to properties in the given object.
|
|
184
184
|
- [`SharedUnionFieldsDeep`](source/shared-union-fields-deep.d.ts) - Create a type with shared fields from a union of object types, deeply traversing nested structures.
|
|
185
185
|
- [`DistributedOmit`](source/distributed-omit.d.ts) - Omits keys from a type, distributing the operation over a union.
|
|
186
|
+
- [`DistributedPick`](source/distributed-pick.d.ts) - Picks keys from a type, distributing the operation over a union.
|
|
186
187
|
|
|
187
188
|
### Type Guard
|
|
188
189
|
|
package/source/asyncify.d.ts
CHANGED
|
@@ -29,4 +29,4 @@ const getFooAsync: AsyncifiedFooGetter = (someArg) => {
|
|
|
29
29
|
|
|
30
30
|
@category Async
|
|
31
31
|
*/
|
|
32
|
-
export type Asyncify<
|
|
32
|
+
export type Asyncify<Function_ extends (...arguments_: any[]) => any> = SetReturnType<Function_, Promise<Awaited<ReturnType<Function_>>>>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type {KeysOfUnion} from './keys-of-union';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Pick keys from a type, distributing the operation over a union.
|
|
5
|
+
|
|
6
|
+
TypeScript's `Pick` doesn't distribute over unions, leading to the erasure of unique properties from union members when picking keys. This creates a type that only retains properties common to all union members, making it impossible to access member-specific properties after the Pick. Essentially, using `Pick` on a union type merges the types into a less specific one, hindering type narrowing and property access based on discriminants. This type solves that.
|
|
7
|
+
|
|
8
|
+
Example:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
type A = {
|
|
12
|
+
discriminant: 'A';
|
|
13
|
+
foo: {
|
|
14
|
+
bar: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type B = {
|
|
19
|
+
discriminant: 'B';
|
|
20
|
+
foo: {
|
|
21
|
+
baz: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type Union = A | B;
|
|
26
|
+
|
|
27
|
+
type PickedUnion = Pick<Union, 'discriminant' | 'foo'>;
|
|
28
|
+
//=> {discriminant: 'A' | 'B', foo: {bar: string} | {baz: string}}
|
|
29
|
+
|
|
30
|
+
const pickedUnion: PickedUnion = createPickedUnion();
|
|
31
|
+
|
|
32
|
+
if (pickedUnion.discriminant === 'A') {
|
|
33
|
+
// We would like to narrow `pickedUnion`'s type
|
|
34
|
+
// to `A` here, but we can't because `Pick`
|
|
35
|
+
// doesn't distribute over unions.
|
|
36
|
+
|
|
37
|
+
pickedUnion.foo.bar;
|
|
38
|
+
//=> Error: Property 'bar' does not exist on type '{bar: string} | {baz: string}'.
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
@example
|
|
43
|
+
```
|
|
44
|
+
type A = {
|
|
45
|
+
discriminant: 'A';
|
|
46
|
+
foo: {
|
|
47
|
+
bar: string;
|
|
48
|
+
};
|
|
49
|
+
extraneous: boolean;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
type B = {
|
|
53
|
+
discriminant: 'B';
|
|
54
|
+
foo: {
|
|
55
|
+
baz: string;
|
|
56
|
+
};
|
|
57
|
+
extraneous: boolean;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Notice that `foo.bar` exists in `A` but not in `B`.
|
|
61
|
+
|
|
62
|
+
type Union = A | B;
|
|
63
|
+
|
|
64
|
+
type PickedUnion = DistributedPick<Union, 'discriminant' | 'foo'>;
|
|
65
|
+
|
|
66
|
+
const pickedUnion: PickedUnion = createPickedUnion();
|
|
67
|
+
|
|
68
|
+
if (pickedUnion.discriminant === 'A') {
|
|
69
|
+
pickedUnion.foo.bar;
|
|
70
|
+
//=> OK
|
|
71
|
+
|
|
72
|
+
pickedUnion.extraneous;
|
|
73
|
+
//=> Error: Property `extraneous` does not exist on type `Pick<A, 'discriminant' | 'foo'>`.
|
|
74
|
+
|
|
75
|
+
pickedUnion.foo.baz;
|
|
76
|
+
//=> Error: `bar` is not a property of `{discriminant: 'A'; a: string}`.
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
@category Object
|
|
81
|
+
*/
|
|
82
|
+
export type DistributedPick<ObjectType, KeyType extends KeysOfUnion<ObjectType>> =
|
|
83
|
+
ObjectType extends unknown
|
|
84
|
+
? Pick<ObjectType, Extract<KeyType, keyof ObjectType>>
|
|
85
|
+
: never;
|
package/source/internal.d.ts
CHANGED
|
@@ -98,7 +98,7 @@ export type BuiltIns = Primitive | void | Date | RegExp;
|
|
|
98
98
|
/**
|
|
99
99
|
Matches non-recursive types.
|
|
100
100
|
*/
|
|
101
|
-
export type NonRecursiveType = BuiltIns | Function | (new (...
|
|
101
|
+
export type NonRecursiveType = BuiltIns | Function | (new (...arguments_: any[]) => unknown);
|
|
102
102
|
|
|
103
103
|
/**
|
|
104
104
|
Returns a boolean for whether the given type is a plain key-value object.
|
|
@@ -38,7 +38,7 @@ Note that types containing overloaded functions are not made deeply readonly due
|
|
|
38
38
|
*/
|
|
39
39
|
export type ReadonlyDeep<T> = T extends BuiltIns
|
|
40
40
|
? T
|
|
41
|
-
: T extends new (...
|
|
41
|
+
: T extends new (...arguments_: any[]) => unknown
|
|
42
42
|
? T // Skip class constructors
|
|
43
43
|
: T extends (...arguments_: any[]) => unknown
|
|
44
44
|
? {} extends ReadonlyObjectDeep<T>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type {IsUnknown} from './is-unknown';
|
|
2
|
-
import type {StaticPartOfArray} from './internal';
|
|
2
|
+
import type {StaticPartOfArray, VariablePartOfArray} from './internal';
|
|
3
3
|
import type {UnknownArray} from './unknown-array';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -32,7 +32,10 @@ type MergeObjectToArray<TArray extends UnknownArray, TObject, TArrayCopy extends
|
|
|
32
32
|
? number extends TObject['length']
|
|
33
33
|
? TObject
|
|
34
34
|
: {
|
|
35
|
-
[K in keyof TArray]:
|
|
35
|
+
[K in keyof TArray]:
|
|
36
|
+
number extends K
|
|
37
|
+
? VariablePartOfArray<TArray>[number]
|
|
38
|
+
: K extends keyof TObject ? TObject[K] : TArray[K]
|
|
36
39
|
}
|
|
37
40
|
: TObject extends object
|
|
38
41
|
// If `TObject` is a object witch key is number like `{0: string, 1: number}`
|
|
@@ -101,14 +104,14 @@ type HandleLog2 = SetParameterType<HandleMessage, {2: string}>;
|
|
|
101
104
|
|
|
102
105
|
@category Function
|
|
103
106
|
*/
|
|
104
|
-
export type SetParameterType<
|
|
107
|
+
export type SetParameterType<Function_ extends (...arguments_: any[]) => unknown, P extends Record<number, unknown>> =
|
|
105
108
|
// Just using `Parameters<Fn>` isn't ideal because it doesn't handle the `this` fake parameter.
|
|
106
|
-
|
|
109
|
+
Function_ extends (this: infer ThisArgument, ...arguments_: infer Arguments) => unknown
|
|
107
110
|
? (
|
|
108
111
|
// If a function did not specify the `this` fake parameter, it will be inferred to `unknown`.
|
|
109
112
|
// We want to detect this situation just to display a friendlier type upon hovering on an IntelliSense-powered IDE.
|
|
110
|
-
IsUnknown<
|
|
111
|
-
? (...arguments_: MergeObjectToArray<Arguments, P>) => ReturnType<
|
|
112
|
-
: (this:
|
|
113
|
+
IsUnknown<ThisArgument> extends true
|
|
114
|
+
? (...arguments_: MergeObjectToArray<Arguments, P>) => ReturnType<Function_>
|
|
115
|
+
: (this: ThisArgument, ...arguments_: MergeObjectToArray<Arguments, P>) => ReturnType<Function_>
|
|
113
116
|
)
|
|
114
|
-
:
|
|
117
|
+
: Function_; // This part should be unreachable
|
|
@@ -17,13 +17,13 @@ type MyWrappedFunction = SetReturnType<MyFunctionThatCanThrow, SomeOtherType | u
|
|
|
17
17
|
|
|
18
18
|
@category Function
|
|
19
19
|
*/
|
|
20
|
-
export type SetReturnType<
|
|
20
|
+
export type SetReturnType<Function_ extends (...arguments_: any[]) => any, TypeToReturn> =
|
|
21
21
|
// Just using `Parameters<Fn>` isn't ideal because it doesn't handle the `this` fake parameter.
|
|
22
|
-
|
|
22
|
+
Function_ extends (this: infer ThisArgument, ...arguments_: infer Arguments) => any ? (
|
|
23
23
|
// If a function did not specify the `this` fake parameter, it will be inferred to `unknown`.
|
|
24
24
|
// We want to detect this situation just to display a friendlier type upon hovering on an IntelliSense-powered IDE.
|
|
25
|
-
IsUnknown<
|
|
25
|
+
IsUnknown<ThisArgument> extends true ? (...arguments_: Arguments) => TypeToReturn : (this: ThisArgument, ...arguments_: Arguments) => TypeToReturn
|
|
26
26
|
) : (
|
|
27
27
|
// This part should be unreachable, but we make it meaningful just in case…
|
|
28
|
-
(...arguments_: Parameters<
|
|
28
|
+
(...arguments_: Parameters<Function_>) => TypeToReturn
|
|
29
29
|
);
|