-
Notifications
You must be signed in to change notification settings - Fork 12.3k
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
4.2 breaks string literal conditional type checking. #42644
Comments
Seems like we didn't used to simplify |
Hmm, this was my train of thought - Since string literal templates should only allow literals as input then it makes sense that only a literal passed into a template can actually resolve to a literal type. type AB<T extends string> = T extends `${string & T}AB` ? T : never;
type ABTest = AB<'foo'>; // makes sense that this is never. The condition is: 'foo' extends 'fooAB'
type A<T extends string> = T extends `${string & T}A` ? T : never;
type ATest = A<'foo'>; // makes sense that this is never. The condition is: 'foo' extends 'fooA'
type Same<T> = T extends `${string & T}` ? T : never;
type SameTest = Same<'foo'>; // Should be 'foo' because - The condition is: 'foo' extends 'foo' Next is for the sake of consistency and maintaining the spirt of literals being a narrowing mechanism. //4.1: resolves in intellisense to `${string}`
//4.2: resolves in intellisense to string
type Foo = `${string & string}`;
//4.1: resolves in intellisense to `${number}`
//4.2: resolves in intellisense to `${number}`
type Num = `${number & number}`; I am using a string literal template, and I would hope that a string literal template would ALWAYS resolve to a string literal, and not promote the contents of the
The above just doesn't seem safe to allow. Side note: this breaks all of my type declaration code if this is not a regression. |
@ahejlsberg thoughts? |
Daniel is correct, we used to not reduce I'd suggest writing the type StringLiteral<T> = T extends string ? string extends T ? never : T : never; That works in both 4.1 and 4.2 and really makes more sense--it expresses anything that extends |
Thanks, and that's a super clever alternative. Thank you all for your time on this! |
Bug Report
In TypeScript 4.1, a type can be constrained conditionally to be a string literal. In 4.2 conditionals can not enforce string literals
🔎 Search Terms
string literal, conditional types, breaking change
🕗 Version & Regression Information
⏯ Playground Link
Playground 4.1
Playground 4.2
💻 Code
🙁 Actual behavior
TypeScript 4.2 does not produce compiler errors when the type is too wide.
🙂 Expected behavior
Produces compiler errors when the type is too wide.
The text was updated successfully, but these errors were encountered: