type-fest 3.2.0 → 3.4.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 +3 -3
- package/readme.md +13 -26
- package/source/async-return-type.d.ts +1 -1
- package/source/asyncify.d.ts +1 -1
- package/source/exact.d.ts +8 -21
- package/source/global-this.d.ts +21 -0
- package/source/internal.d.ts +102 -0
- package/source/join.d.ts +10 -5
- package/source/jsonify.d.ts +51 -50
- package/source/set-non-nullable.d.ts +5 -10
- package/source/set-return-type.d.ts +5 -7
package/index.d.ts
CHANGED
|
@@ -101,5 +101,6 @@ export type {Get} from './source/get';
|
|
|
101
101
|
export type {LastArrayElement} from './source/last-array-element';
|
|
102
102
|
|
|
103
103
|
// Miscellaneous
|
|
104
|
+
export type {GlobalThis} from './source/global-this';
|
|
104
105
|
export type {PackageJson} from './source/package-json';
|
|
105
106
|
export type {TsConfigJson} from './source/tsconfig-json';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "type-fest",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "A collection of essential TypeScript types",
|
|
5
5
|
"license": "(MIT OR CC0-1.0)",
|
|
6
6
|
"repository": "sindresorhus/type-fest",
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"@sindresorhus/tsconfig": "~0.7.0",
|
|
38
38
|
"expect-type": "^0.15.0",
|
|
39
39
|
"tsd": "^0.24.1",
|
|
40
|
-
"typescript": "^4.
|
|
41
|
-
"xo": "^0.
|
|
40
|
+
"typescript": "^4.9.3",
|
|
41
|
+
"xo": "^0.53.1"
|
|
42
42
|
},
|
|
43
43
|
"xo": {
|
|
44
44
|
"rules": {
|
package/readme.md
CHANGED
|
@@ -68,20 +68,6 @@
|
|
|
68
68
|
</sub>
|
|
69
69
|
</div>
|
|
70
70
|
</a>
|
|
71
|
-
<br>
|
|
72
|
-
<br>
|
|
73
|
-
<a href="https://sizzy.co/?utm_campaign=github_repo&utm_source=github&utm_medium=referral&utm_content=type-fest&utm_term=sindre">
|
|
74
|
-
<div>
|
|
75
|
-
<img src="https://sindresorhus.com/assets/thanks/sizzy-logo.png" width="240" alt="Sizzy">
|
|
76
|
-
</div>
|
|
77
|
-
<div>
|
|
78
|
-
<sub>
|
|
79
|
-
<b>Before Sizzy:</b> web development is stressing you out, responsive design is hard, you have an overwhelming amount of opened tabs & apps.
|
|
80
|
-
<br>
|
|
81
|
-
<b>After Sizzy:</b> all the tools you need in one place, responsive design is a breeze, no more context switching.
|
|
82
|
-
</sub>
|
|
83
|
-
</div>
|
|
84
|
-
</a>
|
|
85
71
|
</p>
|
|
86
72
|
</div>
|
|
87
73
|
<br>
|
|
@@ -250,6 +236,7 @@ Click the type names for complete docs.
|
|
|
250
236
|
|
|
251
237
|
### Miscellaneous
|
|
252
238
|
|
|
239
|
+
- [`GlobalThis`](source/global-this.d.ts) - Declare locally scoped properties on `globalThis`.
|
|
253
240
|
- [`PackageJson`](source/package-json.d.ts) - Type for [npm's `package.json` file](https://docs.npmjs.com/creating-a-package-json-file). It also includes support for [TypeScript Declaration Files](https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html) and [Yarn Workspaces](https://classic.yarnpkg.com/lang/en/docs/workspaces/).
|
|
254
241
|
- [`TsConfigJson`](source/tsconfig-json.d.ts) - Type for [TypeScript's `tsconfig.json` file](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html).
|
|
255
242
|
|
|
@@ -637,13 +624,13 @@ There are many advanced types most users don't know about.
|
|
|
637
624
|
// Mutate array randomly changing its' elements indexes.
|
|
638
625
|
}
|
|
639
626
|
|
|
640
|
-
function callNTimes<Fn extends (...
|
|
627
|
+
function callNTimes<Fn extends (...arguments_: any[]) => any> (func: Fn, callCount: number) {
|
|
641
628
|
// Type that represents the type of the received function parameters.
|
|
642
629
|
type FunctionParameters = Parameters<Fn>;
|
|
643
630
|
|
|
644
|
-
return function (...
|
|
631
|
+
return function (...arguments_: FunctionParameters) {
|
|
645
632
|
for (let i = 0; i < callCount; i++) {
|
|
646
|
-
func(...
|
|
633
|
+
func(...arguments_);
|
|
647
634
|
}
|
|
648
635
|
}
|
|
649
636
|
}
|
|
@@ -670,7 +657,7 @@ There are many advanced types most users don't know about.
|
|
|
670
657
|
}
|
|
671
658
|
}
|
|
672
659
|
|
|
673
|
-
class InstanceCache<T extends (new (...
|
|
660
|
+
class InstanceCache<T extends (new (...arguments_: any[]) => any)> {
|
|
674
661
|
private ClassConstructor: T;
|
|
675
662
|
private cache: Map<string, InstanceType<T>> = new Map();
|
|
676
663
|
|
|
@@ -678,18 +665,18 @@ There are many advanced types most users don't know about.
|
|
|
678
665
|
this.ClassConstructor = ctr;
|
|
679
666
|
}
|
|
680
667
|
|
|
681
|
-
getInstance (...
|
|
682
|
-
const hash = this.calculateArgumentsHash(...
|
|
668
|
+
getInstance (...arguments_: ConstructorParameters<T>): InstanceType<T> {
|
|
669
|
+
const hash = this.calculateArgumentsHash(...arguments_);
|
|
683
670
|
|
|
684
671
|
const existingInstance = this.cache.get(hash);
|
|
685
672
|
if (existingInstance !== undefined) {
|
|
686
673
|
return existingInstance;
|
|
687
674
|
}
|
|
688
675
|
|
|
689
|
-
return new this.ClassConstructor(...
|
|
676
|
+
return new this.ClassConstructor(...arguments_);
|
|
690
677
|
}
|
|
691
678
|
|
|
692
|
-
private calculateArgumentsHash(...
|
|
679
|
+
private calculateArgumentsHash(...arguments_: any[]): string {
|
|
693
680
|
// Calculate hash.
|
|
694
681
|
return 'hash';
|
|
695
682
|
}
|
|
@@ -761,17 +748,17 @@ There are many advanced types most users don't know about.
|
|
|
761
748
|
const instanceCounter: Map<Function, number> = new Map();
|
|
762
749
|
|
|
763
750
|
interface Constructor {
|
|
764
|
-
new(...
|
|
751
|
+
new(...arguments_: any[]): any;
|
|
765
752
|
}
|
|
766
753
|
|
|
767
754
|
// Keep track how many instances of `Constr` constructor have been created.
|
|
768
755
|
function getInstance<
|
|
769
756
|
Constr extends Constructor,
|
|
770
|
-
|
|
771
|
-
>(constructor: Constr, ...
|
|
757
|
+
Arguments extends ConstructorParameters<Constr>
|
|
758
|
+
>(constructor: Constr, ...arguments_: Arguments): InstanceType<Constr> {
|
|
772
759
|
let count = instanceCounter.get(constructor) || 0;
|
|
773
760
|
|
|
774
|
-
const instance = new constructor(...
|
|
761
|
+
const instance = new constructor(...arguments_);
|
|
775
762
|
|
|
776
763
|
instanceCounter.set(constructor, count + 1);
|
|
777
764
|
|
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<Fn extends (...
|
|
32
|
+
export type Asyncify<Fn extends (...arguments_: any[]) => any> = SetReturnType<Fn, Promise<Awaited<ReturnType<Fn>>>>;
|
package/source/exact.d.ts
CHANGED
|
@@ -1,20 +1,5 @@
|
|
|
1
|
-
import type {KeysOfUnion} from './internal';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
Extract the element of an array that also works for array union.
|
|
5
|
-
|
|
6
|
-
Returns `never` if T is not an array.
|
|
7
|
-
|
|
8
|
-
It creates a type-safe way to access the element type of `unknown` type.
|
|
9
|
-
*/
|
|
10
|
-
type ArrayElement<T> = T extends readonly unknown[] ? T[0] : never;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
Extract the object field type if T is an object and K is a key of T, return `never` otherwise.
|
|
14
|
-
|
|
15
|
-
It creates a type-safe way to access the member type of `unknown` type.
|
|
16
|
-
*/
|
|
17
|
-
type ObjectValue<T, K> = K extends keyof T ? T[K] : never;
|
|
1
|
+
import type {KeysOfUnion, ArrayElement, ObjectValue} from './internal';
|
|
2
|
+
import type {Opaque} from './opaque';
|
|
18
3
|
|
|
19
4
|
/**
|
|
20
5
|
Create a type from `ParameterType` and `InputType` and change keys exclusive to `InputType` to `never`.
|
|
@@ -35,7 +20,7 @@ This is useful for function type-guarding to reject arguments with excess proper
|
|
|
35
20
|
```
|
|
36
21
|
type OnlyAcceptName = {name: string};
|
|
37
22
|
|
|
38
|
-
function onlyAcceptName(
|
|
23
|
+
function onlyAcceptName(arguments_: OnlyAcceptName) {}
|
|
39
24
|
|
|
40
25
|
// TypeScript complains about excess properties when an object literal is provided.
|
|
41
26
|
onlyAcceptName({name: 'name', id: 1});
|
|
@@ -54,7 +39,7 @@ import {Exact} from 'type-fest';
|
|
|
54
39
|
|
|
55
40
|
type OnlyAcceptName = {name: string};
|
|
56
41
|
|
|
57
|
-
function onlyAcceptNameImproved<T extends Exact<OnlyAcceptName, T>>(
|
|
42
|
+
function onlyAcceptNameImproved<T extends Exact<OnlyAcceptName, T>>(arguments_: T) {}
|
|
58
43
|
|
|
59
44
|
const invalidInput = {name: 'name', id: 1};
|
|
60
45
|
onlyAcceptNameImproved(invalidInput); // Compilation error
|
|
@@ -69,5 +54,7 @@ export type Exact<ParameterType, InputType> =
|
|
|
69
54
|
ParameterType extends unknown[] ? Array<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>>
|
|
70
55
|
// In TypeScript, Array is a subtype of ReadonlyArray, so always test Array before ReadonlyArray.
|
|
71
56
|
: ParameterType extends readonly unknown[] ? ReadonlyArray<Exact<ArrayElement<ParameterType>, ArrayElement<InputType>>>
|
|
72
|
-
|
|
73
|
-
|
|
57
|
+
// For Opaque types, internal details are hidden from public, so let's leave it as is.
|
|
58
|
+
: ParameterType extends Opaque<infer OpaqueType, infer OpaqueToken> ? ParameterType
|
|
59
|
+
: ParameterType extends object ? ExactObject<ParameterType, InputType>
|
|
60
|
+
: ParameterType;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Declare locally scoped properties on `globalThis`.
|
|
3
|
+
|
|
4
|
+
When defining a global variable in a declaration file is inappropriate, it can be helpful to define a `type` or `interface` (say `ExtraGlobals`) with the global variable and then cast `globalThis` via code like `globalThis as unknown as ExtraGlobals`.
|
|
5
|
+
|
|
6
|
+
Instead of casting through `unknown`, you can update your `type` or `interface` to extend `GlobalThis` and then directly cast `globalThis`.
|
|
7
|
+
|
|
8
|
+
@example
|
|
9
|
+
```
|
|
10
|
+
import type {GlobalThis} from 'type-fest';
|
|
11
|
+
|
|
12
|
+
type ExtraGlobals = GlobalThis & {
|
|
13
|
+
readonly GLOBAL_TOKEN: string;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
(globalThis as ExtraGlobals).GLOBAL_TOKEN;
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
@category Type
|
|
20
|
+
*/
|
|
21
|
+
export type GlobalThis = typeof globalThis;
|
package/source/internal.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type {Primitive} from './primitive';
|
|
2
|
+
import type {Simplify} from './simplify';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
Returns a boolean for whether the two given types are equal.
|
|
@@ -94,6 +95,22 @@ Extracts the type of an array or tuple minus the first element.
|
|
|
94
95
|
*/
|
|
95
96
|
export type ArrayTail<TArray extends UnknownArrayOrTuple> = TArray extends readonly [unknown, ...infer TTail] ? TTail : [];
|
|
96
97
|
|
|
98
|
+
/**
|
|
99
|
+
Extract the element of an array that also works for array union.
|
|
100
|
+
|
|
101
|
+
Returns `never` if T is not an array.
|
|
102
|
+
|
|
103
|
+
It creates a type-safe way to access the element type of `unknown` type.
|
|
104
|
+
*/
|
|
105
|
+
export type ArrayElement<T> = T extends readonly unknown[] ? T[0] : never;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
Extract the object field type if T is an object and K is a key of T, return `never` otherwise.
|
|
109
|
+
|
|
110
|
+
It creates a type-safe way to access the member type of `unknown` type.
|
|
111
|
+
*/
|
|
112
|
+
export type ObjectValue<T, K> = K extends keyof T ? T[K] : never;
|
|
113
|
+
|
|
97
114
|
/**
|
|
98
115
|
Returns a boolean for whether the string is lowercased.
|
|
99
116
|
*/
|
|
@@ -108,3 +125,88 @@ export type IsUpperCase<T extends string> = T extends Uppercase<T> ? true : fals
|
|
|
108
125
|
Returns a boolean for whether the string is numeric.
|
|
109
126
|
*/
|
|
110
127
|
export type IsNumeric<T extends string> = T extends `${number}` ? true : false;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
Returns a boolean for whether the the type is `any`.
|
|
131
|
+
|
|
132
|
+
@link https://stackoverflow.com/a/49928360/1490091
|
|
133
|
+
*/
|
|
134
|
+
export type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
Returns a boolean for whether the the type is `never`.
|
|
138
|
+
*/
|
|
139
|
+
export type IsNever<T> = [T] extends [never] ? true : false;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
Returns a boolean for whether the the type is `unknown`.
|
|
143
|
+
*/
|
|
144
|
+
export type IsUnknown<T> = IsNever<T> extends false ? T extends unknown ? unknown extends T ? IsAny<T> extends false ? true : false : false : false : false;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
For an object T, if it has any properties that are a union with `undefined`, make those into optional properties instead.
|
|
148
|
+
|
|
149
|
+
@example
|
|
150
|
+
```
|
|
151
|
+
type User = {
|
|
152
|
+
firstName: string;
|
|
153
|
+
lastName: string | undefined;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
type OptionalizedUser = UndefinedToOptional<User>;
|
|
157
|
+
//=> {
|
|
158
|
+
// firstName: string;
|
|
159
|
+
// lastName?: string;
|
|
160
|
+
// }
|
|
161
|
+
```
|
|
162
|
+
*/
|
|
163
|
+
export type UndefinedToOptional<T extends object> = Simplify<
|
|
164
|
+
{
|
|
165
|
+
// Property is not a union with `undefined`, keep it as-is.
|
|
166
|
+
[Key in keyof Pick<T, FilterDefinedKeys<T>>]: T[Key];
|
|
167
|
+
} & {
|
|
168
|
+
// Property _is_ a union with defined value. Set as optional (via `?`) and remove `undefined` from the union.
|
|
169
|
+
[Key in keyof Pick<T, FilterOptionalKeys<T>>]?: Exclude<T[Key], undefined>;
|
|
170
|
+
}
|
|
171
|
+
>;
|
|
172
|
+
|
|
173
|
+
// Returns `never` if the key or property is not jsonable without testing whether the property is required or optional otherwise return the key.
|
|
174
|
+
type BaseKeyFilter<Type, Key extends keyof Type> = Key extends symbol
|
|
175
|
+
? never
|
|
176
|
+
: Type[Key] extends symbol
|
|
177
|
+
? never
|
|
178
|
+
: [(...arguments_: any[]) => any] extends [Type[Key]]
|
|
179
|
+
? never
|
|
180
|
+
: Key;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
Returns the required keys.
|
|
184
|
+
*/
|
|
185
|
+
type FilterDefinedKeys<T extends object> = Exclude<
|
|
186
|
+
{
|
|
187
|
+
[Key in keyof T]: IsAny<T[Key]> extends true
|
|
188
|
+
? Key
|
|
189
|
+
: undefined extends T[Key]
|
|
190
|
+
? never
|
|
191
|
+
: T[Key] extends undefined
|
|
192
|
+
? never
|
|
193
|
+
: BaseKeyFilter<T, Key>;
|
|
194
|
+
}[keyof T],
|
|
195
|
+
undefined
|
|
196
|
+
>;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
Returns the optional keys.
|
|
200
|
+
*/
|
|
201
|
+
type FilterOptionalKeys<T extends object> = Exclude<
|
|
202
|
+
{
|
|
203
|
+
[Key in keyof T]: IsAny<T[Key]> extends true
|
|
204
|
+
? never
|
|
205
|
+
: undefined extends T[Key]
|
|
206
|
+
? T[Key] extends undefined
|
|
207
|
+
? never
|
|
208
|
+
: BaseKeyFilter<T, Key>
|
|
209
|
+
: never;
|
|
210
|
+
}[keyof T],
|
|
211
|
+
undefined
|
|
212
|
+
>;
|
package/source/join.d.ts
CHANGED
|
@@ -23,8 +23,13 @@ const path: Join<[1, 2, 3], '.'> = [1, 2, 3].join('.');
|
|
|
23
23
|
export type Join<
|
|
24
24
|
Strings extends Array<string | number>,
|
|
25
25
|
Delimiter extends string,
|
|
26
|
-
> = Strings extends []
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
> = Strings extends []
|
|
27
|
+
? ''
|
|
28
|
+
: Strings extends [string | number]
|
|
29
|
+
? `${Strings[0]}`
|
|
30
|
+
: Strings extends [
|
|
31
|
+
string | number,
|
|
32
|
+
...infer Rest extends Array<string | number>,
|
|
33
|
+
]
|
|
34
|
+
? `${Strings[0]}${Delimiter}${Join<Rest, Delimiter>}`
|
|
35
|
+
: string;
|
package/source/jsonify.d.ts
CHANGED
|
@@ -1,32 +1,26 @@
|
|
|
1
1
|
import type {JsonPrimitive, JsonValue} from './basic';
|
|
2
2
|
import type {EmptyObject} from './empty-object';
|
|
3
|
-
import type {
|
|
3
|
+
import type {IsAny, UndefinedToOptional} from './internal';
|
|
4
4
|
import type {NegativeInfinity, PositiveInfinity} from './numeric';
|
|
5
5
|
import type {TypedArray} from './typed-array';
|
|
6
6
|
|
|
7
7
|
// Note: The return value has to be `any` and not `unknown` so it can match `void`.
|
|
8
|
-
type NotJsonable = ((...
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// Returns never if the key or property is not jsonable or required otherwise return the key.
|
|
25
|
-
type OptionalKeyFilter<Type, Key extends keyof Type> = undefined extends Type[Key]
|
|
26
|
-
? Type[Key] extends undefined
|
|
27
|
-
? never
|
|
28
|
-
: BaseKeyFilter<Type, Key>
|
|
29
|
-
: never;
|
|
8
|
+
type NotJsonable = ((...arguments_: any[]) => any) | undefined | symbol;
|
|
9
|
+
|
|
10
|
+
type JsonifyTuple<T extends [unknown, ...unknown[]]> = {
|
|
11
|
+
[Key in keyof T]: T[Key] extends NotJsonable ? null : Jsonify<T[Key]>;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type FilterJsonableKeys<T extends object> = {
|
|
15
|
+
[Key in keyof T]: T[Key] extends NotJsonable ? never : Key;
|
|
16
|
+
}[keyof T];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
JSON serialize objects (not including arrays) and classes.
|
|
20
|
+
*/
|
|
21
|
+
type JsonifyObject<T extends object> = {
|
|
22
|
+
[Key in keyof Pick<T, FilterJsonableKeys<T>>]: Jsonify<T[Key]>;
|
|
23
|
+
};
|
|
30
24
|
|
|
31
25
|
/**
|
|
32
26
|
Transform a type to one that is assignable to the `JsonValue` type.
|
|
@@ -41,7 +35,7 @@ An interface cannot be structurally compared to `JsonValue` because an interface
|
|
|
41
35
|
|
|
42
36
|
@example
|
|
43
37
|
```
|
|
44
|
-
import type {Jsonify} from 'type-fest';
|
|
38
|
+
import type {Jsonify, JsonValue} from 'type-fest';
|
|
45
39
|
|
|
46
40
|
interface Geometry {
|
|
47
41
|
type: 'Point' | 'Polygon';
|
|
@@ -85,29 +79,36 @@ const timeJson = JSON.parse(JSON.stringify(time)) as Jsonify<typeof time>;
|
|
|
85
79
|
|
|
86
80
|
@category JSON
|
|
87
81
|
*/
|
|
88
|
-
export type Jsonify<T> =
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
:
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
: T extends
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
82
|
+
export type Jsonify<T> = IsAny<T> extends true
|
|
83
|
+
? any
|
|
84
|
+
: T extends PositiveInfinity | NegativeInfinity
|
|
85
|
+
? null
|
|
86
|
+
: T extends JsonPrimitive
|
|
87
|
+
? T
|
|
88
|
+
: // Instanced primitives are objects
|
|
89
|
+
T extends Number
|
|
90
|
+
? number
|
|
91
|
+
: T extends String
|
|
92
|
+
? string
|
|
93
|
+
: T extends Boolean
|
|
94
|
+
? boolean
|
|
95
|
+
: T extends Map<any, any> | Set<any>
|
|
96
|
+
? EmptyObject
|
|
97
|
+
: T extends TypedArray
|
|
98
|
+
? Record<string, number>
|
|
99
|
+
: T extends NotJsonable
|
|
100
|
+
? never // Non-JSONable type union was found not empty
|
|
101
|
+
: // Any object with toJSON is special case
|
|
102
|
+
T extends {toJSON(): infer J}
|
|
103
|
+
? (() => J) extends () => JsonValue // Is J assignable to JsonValue?
|
|
104
|
+
? J // Then T is Jsonable and its Jsonable value is J
|
|
105
|
+
: Jsonify<J> // Maybe if we look a level deeper we'll find a JsonValue
|
|
106
|
+
: T extends []
|
|
107
|
+
? []
|
|
108
|
+
: T extends [unknown, ...unknown[]]
|
|
109
|
+
? JsonifyTuple<T>
|
|
110
|
+
: T extends ReadonlyArray<infer U>
|
|
111
|
+
? Array<U extends NotJsonable ? null : Jsonify<U>>
|
|
112
|
+
: T extends object
|
|
113
|
+
? JsonifyObject<UndefinedToOptional<T>> // JsonifyObject recursive call for its children
|
|
114
|
+
: never; // Otherwise any other non-object is removed
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import type {Except} from './except';
|
|
2
|
-
import type {Simplify} from './simplify';
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
2
|
Create a type that makes the given keys non-nullable, where the remaining keys are kept as is.
|
|
6
3
|
|
|
@@ -35,10 +32,8 @@ type AllNonNullable = SetNonNullable<Foo>;
|
|
|
35
32
|
|
|
36
33
|
@category Object
|
|
37
34
|
*/
|
|
38
|
-
export type SetNonNullable<BaseType, Keys extends keyof BaseType = keyof BaseType> =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
{[Key in Keys]: NonNullable<BaseType[Key]>}
|
|
44
|
-
>;
|
|
35
|
+
export type SetNonNullable<BaseType, Keys extends keyof BaseType = keyof BaseType> = {
|
|
36
|
+
[Key in keyof BaseType]: Key extends Keys
|
|
37
|
+
? NonNullable<BaseType[Key]>
|
|
38
|
+
: BaseType[Key];
|
|
39
|
+
};
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
type
|
|
2
|
-
type IsNever<T> = [T] extends [never] ? true : false;
|
|
3
|
-
type IsUnknown<T> = IsNever<T> extends false ? T extends unknown ? unknown extends T ? IsAny<T> extends false ? true : false : false : false : false;
|
|
1
|
+
import type {IsUnknown} from './internal';
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
Create a function type with a return type of your choice and the same parameters as the given function type.
|
|
@@ -19,13 +17,13 @@ type MyWrappedFunction = SetReturnType<MyFunctionThatCanThrow, SomeOtherType | u
|
|
|
19
17
|
|
|
20
18
|
@category Function
|
|
21
19
|
*/
|
|
22
|
-
export type SetReturnType<Fn extends (...
|
|
20
|
+
export type SetReturnType<Fn extends (...arguments_: any[]) => any, TypeToReturn> =
|
|
23
21
|
// Just using `Parameters<Fn>` isn't ideal because it doesn't handle the `this` fake parameter.
|
|
24
|
-
Fn extends (this: infer ThisArg, ...
|
|
22
|
+
Fn extends (this: infer ThisArg, ...arguments_: infer Arguments) => any ? (
|
|
25
23
|
// If a function did not specify the `this` fake parameter, it will be inferred to `unknown`.
|
|
26
24
|
// We want to detect this situation just to display a friendlier type upon hovering on an IntelliSense-powered IDE.
|
|
27
|
-
IsUnknown<ThisArg> extends true ? (...
|
|
25
|
+
IsUnknown<ThisArg> extends true ? (...arguments_: Arguments) => TypeToReturn : (this: ThisArg, ...arguments_: Arguments) => TypeToReturn
|
|
28
26
|
) : (
|
|
29
27
|
// This part should be unreachable, but we make it meaningful just in case…
|
|
30
|
-
(...
|
|
28
|
+
(...arguments_: Parameters<Fn>) => TypeToReturn
|
|
31
29
|
);
|