type-fest 3.2.0 → 3.3.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/package.json +3 -3
- package/readme.md +0 -14
- package/source/internal.d.ts +76 -0
- package/source/join.d.ts +10 -5
- package/source/jsonify.d.ts +48 -47
- package/source/set-non-nullable.d.ts +5 -10
- package/source/set-return-type.d.ts +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "type-fest",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.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>
|
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.
|
|
@@ -108,3 +109,78 @@ export type IsUpperCase<T extends string> = T extends Uppercase<T> ? true : fals
|
|
|
108
109
|
Returns a boolean for whether the string is numeric.
|
|
109
110
|
*/
|
|
110
111
|
export type IsNumeric<T extends string> = T extends `${number}` ? true : false;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
Returns a boolean for whether the the type is `any`.
|
|
115
|
+
|
|
116
|
+
@link https://stackoverflow.com/a/49928360/1490091
|
|
117
|
+
*/
|
|
118
|
+
export type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
For an object T, if it has any properties that are a union with `undefined`, make those into optional properties instead.
|
|
122
|
+
|
|
123
|
+
@example
|
|
124
|
+
```
|
|
125
|
+
type User = {
|
|
126
|
+
firstName: string;
|
|
127
|
+
lastName: string | undefined;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
type OptionalizedUser = UndefinedToOptional<User>;
|
|
131
|
+
//=> {
|
|
132
|
+
// firstName: string;
|
|
133
|
+
// lastName?: string;
|
|
134
|
+
// }
|
|
135
|
+
```
|
|
136
|
+
*/
|
|
137
|
+
export type UndefinedToOptional<T extends object> = Simplify<
|
|
138
|
+
{
|
|
139
|
+
// Property is not a union with `undefined`, keep it as-is.
|
|
140
|
+
[Key in keyof Pick<T, FilterDefinedKeys<T>>]: T[Key];
|
|
141
|
+
} & {
|
|
142
|
+
// Property _is_ a union with defined value. Set as optional (via `?`) and remove `undefined` from the union.
|
|
143
|
+
[Key in keyof Pick<T, FilterOptionalKeys<T>>]?: Exclude<T[Key], undefined>;
|
|
144
|
+
}
|
|
145
|
+
>;
|
|
146
|
+
|
|
147
|
+
// Returns `never` if the key or property is not jsonable without testing whether the property is required or optional otherwise return the key.
|
|
148
|
+
type BaseKeyFilter<Type, Key extends keyof Type> = Key extends symbol
|
|
149
|
+
? never
|
|
150
|
+
: Type[Key] extends symbol
|
|
151
|
+
? never
|
|
152
|
+
: [(...args: any[]) => any] extends [Type[Key]]
|
|
153
|
+
? never
|
|
154
|
+
: Key;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
Returns the required keys.
|
|
158
|
+
*/
|
|
159
|
+
type FilterDefinedKeys<T extends object> = Exclude<
|
|
160
|
+
{
|
|
161
|
+
[Key in keyof T]: IsAny<T[Key]> extends true
|
|
162
|
+
? Key
|
|
163
|
+
: undefined extends T[Key]
|
|
164
|
+
? never
|
|
165
|
+
: T[Key] extends undefined
|
|
166
|
+
? never
|
|
167
|
+
: BaseKeyFilter<T, Key>;
|
|
168
|
+
}[keyof T],
|
|
169
|
+
undefined
|
|
170
|
+
>;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
Returns the optional keys.
|
|
174
|
+
*/
|
|
175
|
+
type FilterOptionalKeys<T extends object> = Exclude<
|
|
176
|
+
{
|
|
177
|
+
[Key in keyof T]: IsAny<T[Key]> extends true
|
|
178
|
+
? never
|
|
179
|
+
: undefined extends T[Key]
|
|
180
|
+
? T[Key] extends undefined
|
|
181
|
+
? never
|
|
182
|
+
: BaseKeyFilter<T, Key>
|
|
183
|
+
: never;
|
|
184
|
+
}[keyof T],
|
|
185
|
+
undefined
|
|
186
|
+
>;
|
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
8
|
type NotJsonable = ((...args: any[]) => any) | undefined | symbol;
|
|
9
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;
|
|
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.
|
|
@@ -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,4 +1,5 @@
|
|
|
1
|
-
type IsAny
|
|
1
|
+
import type {IsAny} from './internal';
|
|
2
|
+
|
|
2
3
|
type IsNever<T> = [T] extends [never] ? true : false;
|
|
3
4
|
type IsUnknown<T> = IsNever<T> extends false ? T extends unknown ? unknown extends T ? IsAny<T> extends false ? true : false : false : false : false;
|
|
4
5
|
|