Skip to content

Boolean type property access is not expanded into true | false in a conditional type. #32274

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

Closed
calebmer opened this issue Jul 5, 2019 · 4 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@calebmer
Copy link

calebmer commented Jul 5, 2019

TypeScript Version: 3.5.1

Search Terms: boolean, property

Code

type MyOptions = {
  foo: boolean;
};

type MyType<Options extends MyOptions> = Options["foo"] extends true ? number : string;

declare const a: number | string;
const b: MyType<MyOptions> = a;

Expected behavior: This example should pass, MyType<MyOptions> should be number | string.

Actual behavior: This example fails, MyType<MyOptions> is false.

Playground Link: TypeScript Playground

Related Issues:

#30708 looks similarish. However, it is my understanding that nested union types will not be expanded when compared with a conditional. So [boolean] extends [true] would not be expanded to [true | false] extends [true] and would not be expanded to [true] | [false] extends [true].

I‘d expect this example to pass since we are explicitly putting the union (in this case boolean) under the conditional’s test.

@calebmer
Copy link
Author

calebmer commented Jul 5, 2019

cc @mdgozza who discovered this, I helped make a minimal repro

@jack-williams
Copy link
Collaborator

This is the right behaviour because MyType is not a distributive conditional type; boolean extends true will always be false as the union is viewed atomically.

It needs to be written as:

type Dist<T> = T extends true ? number : string;
type MyType<Options extends MyOptions> = Dist<Options["foo"]>;

@fatcerberus
Copy link

Yep, this is what the documentation means when it says distribution happens over a “naked type parameter”. It’s also why you can easily disable distribution by writing the type as [T] extends [U] ? ...

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Jul 8, 2019
@typescript-bot
Copy link
Collaborator

This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

5 participants