Skip to content

Commit 4c2151a

Browse files
authored
Deprecate If* types in favor of a single If type (#1135)
1 parent bab42f2 commit 4c2151a

25 files changed

+146
-141
lines changed

index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ export type {And} from './source/and.d.ts';
143143
export type {Or} from './source/or.d.ts';
144144
export type {NonEmptyTuple} from './source/non-empty-tuple.d.ts';
145145
export type {FindGlobalInstanceType, FindGlobalType} from './source/find-global-type.d.ts';
146+
export type {If} from './source/if.d.ts';
146147

147148
// Template literal types
148149
export type {CamelCase} from './source/camel-case.d.ts';

readme.md

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -211,41 +211,17 @@ Click the type names for complete docs.
211211

212212
### Type Guard
213213

214-
#### `IsType` vs. `IfType`
215-
216-
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`:
217-
218-
```ts
219-
type IfAny<T, TypeIfAny = true, TypeIfNotAny = false> = (
220-
IsAny<T> extends true ? TypeIfAny : TypeIfNotAny
221-
);
222-
```
223-
224-
#### Usage
225-
226-
```ts
227-
import type {IsAny, IfAny} from 'type-fest';
228-
229-
type ShouldBeTrue = IsAny<any> extends true ? true : false;
230-
//=> true
231-
232-
type ShouldBeFalse = IfAny<'not any'>;
233-
//=> false
234-
235-
type ShouldBeNever = IfAny<'not any', 'not never', 'never'>;
236-
//=> 'never'
237-
```
238-
214+
- [`If`](source/if.d.ts) - An if-else-like type that resolves depending on whether the given `boolean` type is `true` or `false`.
239215
- [`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).
240216
- [`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).
241217
- [`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).
242218
- [`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).
243219
- [`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).
244-
- [`IsAny`](source/is-any.d.ts) - Returns a boolean for whether the given type is `any`. (Conditional version: [`IfAny`](source/if-any.d.ts))
245-
- [`IsNever`](source/is-never.d.ts) - Returns a boolean for whether the given type is `never`. (Conditional version: [`IfNever`](source/if-never.d.ts))
246-
- [`IsUnknown`](source/is-unknown.d.ts) - Returns a boolean for whether the given type is `unknown`. (Conditional version: [`IfUnknown`](source/if-unknown.d.ts))
247-
- [`IsEmptyObject`](source/empty-object.d.ts) - Returns a boolean for whether the type is strictly equal to an empty plain object, the `{}` value. (Conditional version: [`IfEmptyObject`](source/if-empty-object.d.ts))
248-
- [`IsNull`](source/is-null.d.ts) - Returns a boolean for whether the given type is `null`. (Conditional version: [`IfNull`](source/if-null.d.ts))
220+
- [`IsAny`](source/is-any.d.ts) - Returns a boolean for whether the given type is `any`.
221+
- [`IsNever`](source/is-never.d.ts) - Returns a boolean for whether the given type is `never`.
222+
- [`IsUnknown`](source/is-unknown.d.ts) - Returns a boolean for whether the given type is `unknown`.
223+
- [`IsEmptyObject`](source/empty-object.d.ts) - Returns a boolean for whether the type is strictly equal to an empty plain object, the `{}` value.
224+
- [`IsNull`](source/is-null.d.ts) - Returns a boolean for whether the given type is `null`.
249225
- [`IsTuple`](source/is-tuple.d.ts) - Returns a boolean for whether the given array is a tuple.
250226

251227
### JSON
@@ -375,6 +351,7 @@ type ShouldBeNever = IfAny<'not any', 'not never', 'never'>;
375351
- `SetValues` - See [`IterableElement`](source/iterable-element.d.ts)
376352
- `PickByTypes` - See [`ConditionalPick`](source/conditional-pick.d.ts)
377353
- `HomomorphicOmit` - See [`Except`](source/except.d.ts)
354+
- `IfAny`, `IfNever`, `If*` - See [`If`](source/if.d.ts)
378355

379356
## Tips
380357

source/array-tail.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import type {ApplyDefaultOptions, IfArrayReadonly} from './internal/index.d.ts';
1+
import type {If} from './if.js';
2+
import type {ApplyDefaultOptions, IsArrayReadonly} from './internal/index.d.ts';
23
import type {UnknownArray} from './unknown-array.d.ts';
34

45
/**
@@ -63,7 +64,7 @@ export type ArrayTail<TArray extends UnknownArray, Options extends ArrayTailOpti
6364
? TArray extends UnknownArray // For distributing `TArray`
6465
? _ArrayTail<TArray> extends infer Result
6566
? ResolvedOptions['preserveReadonly'] extends true
66-
? IfArrayReadonly<TArray, Readonly<Result>, Result>
67+
? If<IsArrayReadonly<TArray>, Readonly<Result>, Result>
6768
: Result
6869
: never // Should never happen
6970
: never // Should never happen

source/conditional-keys.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import type {IfNever} from './if-never.d.ts';
1+
import type {If} from './if.js';
2+
import type {IsNever} from './is-never.js';
23

34
/**
45
Extract the keys from a type where the value type of the key extends the given `Condition`.
@@ -40,7 +41,7 @@ export type ConditionalKeys<Base, Condition> =
4041
Base[Key] extends Condition
4142
// Retain this key
4243
// If the value for the key extends never, only include it if `Condition` also extends never
43-
? IfNever<Base[Key], IfNever<Condition, Key, never>, Key>
44+
? If<IsNever<Base[Key]>, If<IsNever<Condition>, Key, never>, Key>
4445
// Discard this key since the condition fails.
4546
: never;
4647
// Convert the produced object into a union type of the keys which passed the conditional test.

source/if-any.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type {IsAny} from './is-any.d.ts';
33
/**
44
An if-else-like type that resolves depending on whether the given type is `any`.
55
6+
@deprecated This type will be removed in the next major version. Use the {@link If} type instead.
7+
68
@see {@link IsAny}
79
810
@example

source/if-empty-object.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type {IsEmptyObject} from './empty-object.d.ts';
33
/**
44
An if-else-like type that resolves depending on whether the given type is `{}`.
55
6+
@deprecated This type will be removed in the next major version. Use the {@link If} type instead.
7+
68
@see {@link IsEmptyObject}
79
810
@example

source/if-never.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type {IsNever} from './is-never.d.ts';
33
/**
44
An if-else-like type that resolves depending on whether the given type is `never`.
55
6+
@deprecated This type will be removed in the next major version. Use the {@link If} type instead.
7+
68
@see {@link IsNever}
79
810
@example

source/if-null.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type {IsNull} from './is-null.d.ts';
33
/**
44
An if-else-like type that resolves depending on whether the given type is `null`.
55
6+
@deprecated This type will be removed in the next major version. Use the {@link If} type instead.
7+
68
@see {@link IsNull}
79
810
@example

source/if-unknown.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type {IsUnknown} from './is-unknown.d.ts';
33
/**
44
An if-else-like type that resolves depending on whether the given type is `unknown`.
55
6+
@deprecated This type will be removed in the next major version. Use the {@link If} type instead.
7+
68
@see {@link IsUnknown}
79
810
@example

source/if.d.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import type {IsNever} from './is-never.js';
2+
3+
/**
4+
An if-else-like type that resolves depending on whether the given `boolean` type is `true` or `false`.
5+
6+
Use-cases:
7+
- You can use this in combination with `Is*` types to create an if-else-like experience. For example, `If<IsAny<any>, 'is any', 'not any'>`.
8+
9+
Note:
10+
- Returns a union of if branch and else branch if the given type is `boolean` or `any`. For example, `If<boolean, 'Y', 'N'>` will return `'Y' | 'N'`.
11+
- Returns the else branch if the given type is `never`. For example, `If<never, 'Y', 'N'>` will return `'N'`.
12+
13+
@example
14+
```
15+
import {If} from 'type-fest';
16+
17+
type A = If<true, 'yes', 'no'>;
18+
//=> 'yes'
19+
20+
type B = If<false, 'yes', 'no'>;
21+
//=> 'no'
22+
23+
type C = If<boolean, 'yes', 'no'>;
24+
//=> 'yes' | 'no'
25+
26+
type D = If<any, 'yes', 'no'>;
27+
//=> 'yes' | 'no'
28+
29+
type E = If<never, 'yes', 'no'>;
30+
//=> 'no'
31+
```
32+
33+
@example
34+
```
35+
import {If, IsAny, IsNever} from 'type-fest';
36+
37+
type A = If<IsAny<unknown>, 'is any', 'not any'>;
38+
//=> 'not any'
39+
40+
type B = If<IsNever<never>, 'is never', 'not never'>;
41+
//=> 'is never'
42+
```
43+
44+
@example
45+
```
46+
import {If, IsEqual} from 'type-fest';
47+
48+
type IfEqual<T, U, IfBranch, ElseBranch> = If<IsEqual<T, U>, IfBranch, ElseBranch>;
49+
50+
type A = IfEqual<string, string, 'equal', 'not equal'>;
51+
//=> 'equal'
52+
53+
type B = IfEqual<string, number, 'equal', 'not equal'>;
54+
//=> 'not equal'
55+
```
56+
57+
@category Type Guard
58+
@category Utilities
59+
*/
60+
export type If<Type extends boolean, IfBranch, ElseBranch> =
61+
IsNever<Type> extends true
62+
? ElseBranch
63+
: Type extends true
64+
? IfBranch
65+
: ElseBranch;

0 commit comments

Comments
 (0)