type-fest 3.7.2 → 3.8.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 CHANGED
@@ -55,6 +55,7 @@ export type {Jsonify} from './source/jsonify';
55
55
  export type {Jsonifiable} from './source/jsonifiable';
56
56
  export type {Schema} from './source/schema';
57
57
  export type {LiteralToPrimitive} from './source/literal-to-primitive';
58
+ export type {LiteralToPrimitiveDeep} from './source/literal-to-primitive-deep';
58
59
  export type {
59
60
  PositiveInfinity,
60
61
  NegativeInfinity,
@@ -84,6 +85,12 @@ export type {
84
85
  IsBooleanLiteral,
85
86
  IsSymbolLiteral,
86
87
  } from './source/is-literal';
88
+ export type {IsAny} from './source/is-any';
89
+ export type {IfAny} from './source/if-any';
90
+ export type {IsNever} from './source/is-never';
91
+ export type {IfNever} from './source/if-never';
92
+ export type {IsUnknown} from './source/is-unknown';
93
+ export type {IfUnknown} from './source/if-unknown';
87
94
 
88
95
  // Template literal types
89
96
  export type {CamelCase} from './source/camel-case';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-fest",
3
- "version": "3.7.2",
3
+ "version": "3.8.0",
4
4
  "description": "A collection of essential TypeScript types",
5
5
  "license": "(MIT OR CC0-1.0)",
6
6
  "repository": "sindresorhus/type-fest",
package/readme.md CHANGED
@@ -157,6 +157,7 @@ Click the type names for complete docs.
157
157
  - [`ConditionalExcept`](source/conditional-except.d.ts) - Like `Omit` except it removes properties from a shape where the values extend the given `Condition` type.
158
158
  - [`UnionToIntersection`](source/union-to-intersection.d.ts) - Convert a union type to an intersection type.
159
159
  - [`LiteralToPrimitive`](source/literal-to-primitive.d.ts) - Convert a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types) to the [primitive type](source/primitive.d.ts) it belongs to.
160
+ - [`LiteralToPrimitiveDeep`](source/literal-to-primitive-deep.d.ts) - Like `LiteralToPrimitive` except it converts literal types inside an object or array deeply.
160
161
  - [`Stringified`](source/stringified.d.ts) - Create a type with the keys of the given type changed to `string` type.
161
162
  - [`IterableElement`](source/iterable-element.d.ts) - Get the element type of an `Iterable`/`AsyncIterable`. For example, an array or a generator.
162
163
  - [`Entry`](source/entry.d.ts) - Create a type that represents the type of an entry of a collection.
@@ -173,12 +174,43 @@ Click the type names for complete docs.
173
174
  - [`HasRequiredKeys`](source/has-required-keys.d.ts) - Create a `true`/`false` type depending on whether the given type has any required fields.
174
175
  - [`Spread`](source/spread.d.ts) - Mimic the type inferred by TypeScript when merging two objects or two arrays/tuples using the spread syntax.
175
176
  - [`IsEqual`](source/is-equal.d.ts) - Returns a boolean for whether the two given types are equal.
177
+ - [`TaggedUnion`](source/tagged-union.d.ts) - Create a union of types that share a common discriminant property.
178
+
179
+ ### Type Guard
180
+
181
+ #### `IsType` vs. `IfType`
182
+
183
+ For every `IsT` type (e.g. `IsAny`), there is an associated `IfT` type that can help simplify conditional types. While the `IsT` types return a `boolean`, the `IfT` types act like an `If`/`Else` - they resolve to the given `TypeIfT` or `TypeIfNotT` depending on whether `IsX` is `true` or not. By default, `IfT` returns a `boolean`:
184
+
185
+ ```ts
186
+ type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = (
187
+ IsAny<T> extends true ? TypeIfAny : TypeIfNotAny
188
+ );
189
+ ```
190
+
191
+ #### Usage
192
+
193
+ ```ts
194
+ import type {IsAny, IfAny} from 'type-fest';
195
+
196
+ type ShouldBeTrue = IsAny<any> extends true ? true : false;
197
+ //=> true
198
+
199
+ type ShouldBeFalse = IfAny<'not any'>;
200
+ //=> false
201
+
202
+ type ShouldBeNever = IfAny<'not any', 'not never', 'never'>;
203
+ //=> 'never'
204
+ ```
205
+
176
206
  - [`IsLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
177
207
  - [`IsStringLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `string` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
178
208
  - [`IsNumericLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `number` or `bigint` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
179
209
  - [`IsBooleanLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `true` or `false` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
180
210
  - [`IsSymbolLiteral`](source/is-literal.d.ts) - Returns a boolean for whether the given type is a `symbol` [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types).
181
- - [`TaggedUnion`](source/tagged-union.d.ts) - Create a union of types that share a common discriminant property.
211
+ - [`IsAny`](source/is-any.d.ts) - Returns a boolean for whether the given type is `any`. (Conditional version: [`IfAny`](source/if-any.d.ts).)
212
+ - [`IsNever`](source/is-never.d.ts) - Returns a boolean for whether the given type is `never`. (Conditional version: [`IfNever`](source/if-never.d.ts).)
213
+ - [`IsUnknown`](source/is-unknown.d.ts) - Returns a boolean for whether the given type is `unknown`. (Conditional version: [`IfUnknown`](source/if-unknown.d.ts).)
182
214
 
183
215
  ### JSON
184
216
 
@@ -0,0 +1,24 @@
1
+ import type {IsAny} from './is-any';
2
+
3
+ /**
4
+ An if-else-like type that resolves depending on whether the given type is `any`.
5
+
6
+ @see {@link IsAny}
7
+
8
+ @example
9
+ ```
10
+ import type {IfAny} from 'type-fest';
11
+
12
+ type ShouldBeTrue = IfAny<any>;
13
+ //=> true
14
+
15
+ type ShouldBeBar = IfAny<'not any', 'foo', 'bar'>;
16
+ //=> 'bar'
17
+ ```
18
+
19
+ @category Type Guard
20
+ @category Utilities
21
+ */
22
+ export type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = (
23
+ IsAny<T> extends true ? TypeIfAny : TypeIfNotAny
24
+ );
@@ -0,0 +1,24 @@
1
+ import type {IsNever} from './is-never';
2
+
3
+ /**
4
+ An if-else-like type that resolves depending on whether the given type is `never`.
5
+
6
+ @see {@link IsNever}
7
+
8
+ @example
9
+ ```
10
+ import type {IfNever} from 'type-fest';
11
+
12
+ type ShouldBeTrue = IfNever<never>;
13
+ //=> true
14
+
15
+ type ShouldBeBar = IfNever<'not never', 'foo', 'bar'>;
16
+ //=> 'bar'
17
+ ```
18
+
19
+ @category Type Guard
20
+ @category Utilities
21
+ */
22
+ export type IfNever<T, TypeIfNever = true, TypeIfNotNever = false> = (
23
+ IsNever<T> extends true ? TypeIfNever : TypeIfNotNever
24
+ );
@@ -0,0 +1,24 @@
1
+ import type {IsUnknown} from './is-unknown';
2
+
3
+ /**
4
+ An if-else-like type that resolves depending on whether the given type is `unknown`.
5
+
6
+ @see {@link IsUnknown}
7
+
8
+ @example
9
+ ```
10
+ import type {IfUnknown} from 'type-fest';
11
+
12
+ type ShouldBeTrue = IfUnknown<unknown>;
13
+ //=> true
14
+
15
+ type ShouldBeBar = IfUnknown<'not unknown', 'foo', 'bar'>;
16
+ //=> 'bar'
17
+ ```
18
+
19
+ @category Type Guard
20
+ @category Utilities
21
+ */
22
+ export type IfUnknown<T, TypeIfUnknown = true, TypeIfNotUnknown = false> = (
23
+ IsUnknown<T> extends true ? TypeIfUnknown : TypeIfNotUnknown
24
+ );
@@ -1,6 +1,7 @@
1
1
  import type {Primitive} from './primitive';
2
2
  import type {Simplify} from './simplify';
3
3
  import type {Trim} from './trim';
4
+ import type {IsAny} from './is-any';
4
5
 
5
6
  /**
6
7
  Infer the length of the given array `<T>`.
@@ -158,23 +159,6 @@ export type IsNumeric<T extends string> = T extends `${number}`
158
159
  : false
159
160
  : false;
160
161
 
161
- /**
162
- Returns a boolean for whether the the type is `any`.
163
-
164
- @link https://stackoverflow.com/a/49928360/1490091
165
- */
166
- export type IsAny<T> = 0 extends 1 & T ? true : false;
167
-
168
- /**
169
- Returns a boolean for whether the the type is `never`.
170
- */
171
- export type IsNever<T> = [T] extends [never] ? true : false;
172
-
173
- /**
174
- Returns a boolean for whether the the type is `unknown`.
175
- */
176
- export type IsUnknown<T> = IsNever<T> extends false ? T extends unknown ? unknown extends T ? IsAny<T> extends false ? true : false : false : false : false;
177
-
178
162
  /**
179
163
  For an object T, if it has any properties that are a union with `undefined`, make those into optional properties instead.
180
164
 
@@ -262,3 +246,8 @@ export type HasMultipleCallSignatures<T extends (...arguments: any[]) => unknown
262
246
  Returns a boolean for whether the given `boolean` is not `false`.
263
247
  */
264
248
  export type IsNotFalse<T extends boolean> = [T] extends [false] ? false : true;
249
+
250
+ /**
251
+ Returns a boolean for whether the given type is `null`.
252
+ */
253
+ export type IsNull<T> = [T] extends [null] ? true : false;
@@ -0,0 +1,29 @@
1
+ /**
2
+ Returns a boolean for whether the given type is `any`.
3
+
4
+ @link https://stackoverflow.com/a/49928360/1490091
5
+
6
+ Useful in type utilities, such as disallowing `any`s to be passed to a function.
7
+
8
+ @example
9
+ ```
10
+ import type {IsAny} from 'type-fest';
11
+
12
+ const typedObject = {a: 1, b: 2} as const;
13
+ const anyObject: any = {a: 1, b: 2};
14
+
15
+ function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(obj: O, key: K) {
16
+ return obj[key];
17
+ }
18
+
19
+ const typedA = get(typedObject, 'a');
20
+ //=> 1
21
+
22
+ const anyA = get(anyObject, 'a');
23
+ //=> any
24
+ ```
25
+
26
+ @category Type Guard
27
+ @category Utilities
28
+ */
29
+ export type IsAny<T> = 0 extends 1 & T ? true : false;
@@ -21,6 +21,7 @@ type Includes<Value extends readonly any[], Item> =
21
21
  : false;
22
22
  ```
23
23
 
24
+ @category Type Guard
24
25
  @category Utilities
25
26
  */
26
27
  export type IsEqual<A, B> =
@@ -1,6 +1,7 @@
1
1
  import type {Primitive} from './primitive';
2
2
  import type {Numeric} from './numeric';
3
- import type {IsNever, IsNotFalse} from './internal';
3
+ import type {IsNotFalse} from './internal';
4
+ import type {IsNever} from './is-never';
4
5
 
5
6
  /**
6
7
  Returns a boolean for whether the given type `T` is the specified `LiteralType`.
@@ -77,8 +78,8 @@ const output = capitalize('hello, world!');
77
78
  //=> 'Hello, world!'
78
79
  ```
79
80
 
80
- @category Utilities
81
81
  @category Type Guard
82
+ @category Utilities
82
83
  */
83
84
  export type IsStringLiteral<T> = LiteralCheck<T, string>;
84
85
 
@@ -125,8 +126,8 @@ endsWith('abc123', end);
125
126
  //=> boolean
126
127
  ```
127
128
 
128
- @category Utilities
129
129
  @category Type Guard
130
+ @category Utilities
130
131
  */
131
132
  export type IsNumericLiteral<T> = LiteralChecks<T, Numeric>;
132
133
 
@@ -165,8 +166,8 @@ const eitherId = getId({asString: runtimeBoolean});
165
166
  //=> number | string
166
167
  ```
167
168
 
168
- @category Utilities
169
169
  @category Type Guard
170
+ @category Utilities
170
171
  */
171
172
  export type IsBooleanLiteral<T> = LiteralCheck<T, boolean>;
172
173
 
@@ -200,8 +201,8 @@ get({[symbolValue]: 1} as const, symbolValue);
200
201
  //=> number
201
202
  ```
202
203
 
203
- @category Utilities
204
204
  @category Type Guard
205
+ @category Utilities
205
206
  */
206
207
  export type IsSymbolLiteral<T> = LiteralCheck<T, symbol>;
207
208
 
@@ -246,7 +247,7 @@ stripLeading(str, 'abc');
246
247
  //=> string
247
248
  ```
248
249
 
249
- @category Utilities
250
250
  @category Type Guard
251
+ @category Utilities
251
252
  */
252
253
  export type IsLiteral<T extends Primitive> = IsNotFalse<IsLiteralUnion<T>>;
@@ -0,0 +1,49 @@
1
+ /**
2
+ Returns a boolean for whether the given type is `never`.
3
+
4
+ @link https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919
5
+ @link https://stackoverflow.com/a/53984913/10292952
6
+ @link https://www.zhenghao.io/posts/ts-never
7
+
8
+ Useful in type utilities, such as checking if something does not occur.
9
+
10
+ @example
11
+ ```
12
+ import type {IsNever} from 'type-fest';
13
+
14
+ type And<A, B> =
15
+ A extends true
16
+ ? B extends true
17
+ ? true
18
+ : false
19
+ : false;
20
+
21
+ // https://github.com/andnp/SimplyTyped/blob/master/src/types/strings.ts
22
+ type AreStringsEqual<A extends string, B extends string> =
23
+ And<
24
+ IsNever<Exclude<A, B>> extends true ? true : false,
25
+ IsNever<Exclude<B, A>> extends true ? true : false
26
+ >;
27
+
28
+ type EndIfEqual<I extends string, O extends string> =
29
+ AreStringsEqual<I, O> extends true
30
+ ? never
31
+ : void;
32
+
33
+ function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
34
+ if (input === output) {
35
+ process.exit(0);
36
+ }
37
+ }
38
+
39
+ endIfEqual('abc', 'abc');
40
+ //=> never
41
+
42
+ endIfEqual('abc', '123');
43
+ //=> void
44
+ ```
45
+
46
+ @category Type Guard
47
+ @category Utilities
48
+ */
49
+ export type IsNever<T> = [T] extends [never] ? true : false;
@@ -0,0 +1,52 @@
1
+ import type {IsNull} from './internal';
2
+
3
+ /**
4
+ Returns a boolean for whether the given type is `unknown`.
5
+
6
+ @link https://github.com/dsherret/conditional-type-checks/pull/16
7
+
8
+ Useful in type utilities, such as when dealing with unknown data from API calls.
9
+
10
+ @example
11
+ ```
12
+ import type {IsUnknown} from 'type-fest';
13
+
14
+ // https://github.com/pajecawav/tiny-global-store/blob/master/src/index.ts
15
+ type Action<TState, TPayload = void> =
16
+ IsUnknown<TPayload> extends true
17
+ ? (state: TState) => TState,
18
+ : (state: TState, payload: TPayload) => TState;
19
+
20
+ class Store<TState> {
21
+ constructor(private state: TState) {}
22
+
23
+ execute<TPayload = void>(action: Action<TState, TPayload>, payload?: TPayload): TState {
24
+ this.state = action(this.state, payload);
25
+ return this.state;
26
+ }
27
+
28
+ // ... other methods
29
+ }
30
+
31
+ const store = new Store({value: 1});
32
+ declare const someExternalData: unknown;
33
+
34
+ store.execute(state => ({value: state.value + 1}));
35
+ //=> `TPayload` is `void`
36
+
37
+ store.execute((state, payload) => ({value: state.value + payload}), 5);
38
+ //=> `TPayload` is `5`
39
+
40
+ store.execute((state, payload) => ({value: state.value + payload}), someExternalData);
41
+ //=> Errors: `action` is `(state: TState) => TState`
42
+ ```
43
+
44
+ @category Utilities
45
+ */
46
+ export type IsUnknown<T> = (
47
+ unknown extends T // `T` can be `unknown` or `any`
48
+ ? IsNull<T> extends false // `any` can be `null`, but `unknown` can't be
49
+ ? true
50
+ : false
51
+ : false
52
+ );
@@ -1,8 +1,9 @@
1
1
  import type {JsonPrimitive, JsonValue} from './basic';
2
2
  import type {EmptyObject} from './empty-object';
3
- import type {IsAny, UndefinedToOptional} from './internal';
3
+ import type {UndefinedToOptional} from './internal';
4
4
  import type {NegativeInfinity, PositiveInfinity} from './numeric';
5
5
  import type {TypedArray} from './typed-array';
6
+ import type {IsAny} from './is-any';
6
7
 
7
8
  // Note: The return value has to be `any` and not `unknown` so it can match `void`.
8
9
  type NotJsonable = ((...arguments_: any[]) => any) | undefined | symbol;
@@ -0,0 +1,36 @@
1
+ import type {LiteralToPrimitive} from './literal-to-primitive';
2
+ import type {OmitIndexSignature} from './omit-index-signature';
3
+
4
+ /**
5
+ Like `LiteralToPrimitive` except it converts literal types inside an object or array deeply.
6
+
7
+ For example, given a constant object, it returns a new object type with the same keys but with all the values converted to primitives.
8
+
9
+ @see LiteralToPrimitive
10
+
11
+ Use-case: Deal with data that is imported from a JSON file.
12
+
13
+ @example
14
+ ```
15
+ import type {LiteralToPrimitiveDeep, TsConfigJson} from 'type-fest';
16
+ import tsconfig from 'path/to/tsconfig.json';
17
+
18
+ function doSomethingWithTSConfig(config: LiteralToPrimitiveDeep<TsConfigJson>) { ... }
19
+
20
+ // No casting is needed to pass the type check
21
+ doSomethingWithTSConfig(tsconfig);
22
+
23
+ // If LiteralToPrimitiveDeep is not used, you need to cast the imported data like this:
24
+ doSomethingWithTSConfig(tsconfig as TsConfigJson);
25
+ ```
26
+
27
+ @category Type
28
+ @category Object
29
+ */
30
+ export type LiteralToPrimitiveDeep<T> = T extends object
31
+ ? T extends Array<infer U>
32
+ ? Array<LiteralToPrimitiveDeep<U>>
33
+ : {
34
+ [K in keyof OmitIndexSignature<T>]: LiteralToPrimitiveDeep<T[K]>;
35
+ }
36
+ : LiteralToPrimitive<T>;
@@ -1,4 +1,4 @@
1
- import type {IsUnknown} from './internal';
1
+ import type {IsUnknown} from './is-unknown';
2
2
 
3
3
  /**
4
4
  Create a function type with a return type of your choice and the same parameters as the given function type.