Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nullish coalescing operator but for conditional types #58629

Open
6 tasks done
RebeccaStevens opened this issue May 23, 2024 · 2 comments
Open
6 tasks done

Nullish coalescing operator but for conditional types #58629

RebeccaStevens opened this issue May 23, 2024 · 2 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@RebeccaStevens
Copy link

RebeccaStevens commented May 23, 2024

πŸ” Search Terms

nullish coalescing operator
conditional types

βœ… Viability Checklist

⭐ Suggestion

Add syntactic sugar to allow this:

type T = A extends B ?? C

to be shorthand of:

type T = A extends B ? A : C

πŸ“ƒ Motivating Example

When working with large complicated types, it is often that you need to check that a type extends another type before passing it as a type argument to another type.

For example, ensuring it is an array before passing it to something that requires it to be an array:

type Foo<T> = Bar<
    Some<Really<Deep<Complex<Type<Utility<T>>>>>> extends readonly unknown[]
        ? Some<Really<Deep<Complex<Type<Utility<T>>>>>>
        : never
>;

type Bar<T extends readonly unknown[]> = ...;

The more complex the type you need to check, the more you need to repeat yourself to pass the same type in again.

This proposal aims to address that.

type Foo<T> = Bar<
    Some<Really<Deep<Complex<Type<Utility<T>>>>>> extends readonly unknown[] ?? never
>;

πŸ’» Use Cases

  1. What do you want to use this for?

Making my type code more readable and easier to maintain.

  1. What shortcomings exist with current approaches?

The need to repeat yourself. Updates to the type need to be make in two places.

  1. What workarounds are you using in the meantime?

The long-form syntax.

@whzx5byb
Copy link

To not repeat yourself, you can use infer R extends as a workaround. Not sure what your real-world code looks like but this may work.

type Foo<T> = Bar<
    [Some<Really<Deep<Complex<Type<Utility<T>>>>>>] extends [infer R extends readonly unknown[]]
        ? R
        : never
>;

@jcalz
Copy link
Contributor

jcalz commented May 23, 2024

You can just define your own utility type like type OrElse<A, B, C> = [A] extends [B] ? A : C and use that. TS is unlikely to add new syntax if utility types can serve the same purpose, even if you'd prefer to see A extends B ?? C and not OrElse<A, B, C>.

Also, bikeshedding syntax: ?? doesn't seem to have the same meaning in your suggestion as it does in JS. Where is the "nullishness" here? Maybe if B is {}? I'd expect a type like A??C to evaluate to A unless it is nullish, and then C otherwise, so that string ?? number is string, but null ?? number is number. Since that's not what you're suggesting, the particular syntax would be misleading.

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature labels Jun 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants