PokéRogue
    Preparing search index...

    Type Alias If<Type, IfBranch, ElseBranch>

    If: IsNever<Type> extends true
        ? ElseBranch
        : Type extends true ? IfBranch : ElseBranch

    An if-else-like type that resolves depending on whether the given boolean type is true or false.

    Use-cases:

    • 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'>.

    Note:

    • 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'.
    • Returns the else branch if the given type is never. For example, If<never, 'Y', 'N'> will return 'N'.

    Type Parameters

    • Type extends boolean
    • IfBranch
    • ElseBranch
    import type {If} from 'type-fest';

    type A = If<true, 'yes', 'no'>;
    //=> 'yes'

    type B = If<false, 'yes', 'no'>;
    //=> 'no'

    type C = If<boolean, 'yes', 'no'>;
    //=> 'yes' | 'no'

    type D = If<any, 'yes', 'no'>;
    //=> 'yes' | 'no'

    type E = If<never, 'yes', 'no'>;
    //=> 'no'
    import type {If, IsAny, IsNever} from 'type-fest';

    type A = If<IsAny<unknown>, 'is any', 'not any'>;
    //=> 'not any'

    type B = If<IsNever<never>, 'is never', 'not never'>;
    //=> 'is never'
    import type {If, IsEqual} from 'type-fest';

    type IfEqual<T, U, IfBranch, ElseBranch> = If<IsEqual<T, U>, IfBranch, ElseBranch>;

    type A = IfEqual<string, string, 'equal', 'not equal'>;
    //=> 'equal'

    type B = IfEqual<string, number, 'equal', 'not equal'>;
    //=> 'not equal'

    Note: Sometimes using the If type can make an implementation non–tail-recursive, which can impact performance. In such cases, it’s better to use a conditional directly. Refer to the following example:

    import type {If, IsEqual, StringRepeat} from 'type-fest';

    type HundredZeroes = StringRepeat<'0', 100>;

    // The following implementation is not tail recursive
    type Includes<S extends string, Char extends string> =
    S extends `${infer First}${infer Rest}`
    ? If<IsEqual<First, Char>,
    'found',
    Includes<Rest, Char>>
    : 'not found';

    // Hence, instantiations with long strings will fail
    // @ts-expect-error
    type Fails = Includes<HundredZeroes, '1'>;
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    // Error: Type instantiation is excessively deep and possibly infinite.

    // However, if we use a simple conditional instead of `If`, the implementation becomes tail-recursive
    type IncludesWithoutIf<S extends string, Char extends string> =
    S extends `${infer First}${infer Rest}`
    ? IsEqual<First, Char> extends true
    ? 'found'
    : IncludesWithoutIf<Rest, Char>
    : 'not found';

    // Now, instantiations with long strings will work
    type Works = IncludesWithoutIf<HundredZeroes, '1'>;
    //=> 'not found'