Aliasing a type in a conditional type changes the result
See original GitHub issueBug Report
🔎 Search Terms
any, alias, conditional type,
🕗 Version & Regression Information
All versions are effected.
⏯ Playground Link
💻 Code
interface User {
id: number;
username: string;
}
type Q<T> = {a: keyof T & string };
type t1 = Q<any> extends Q<User> ? true : never;
type qAny = Q<any>;
type t2 = qAny extends Q<User> ? true : never;
🙁 Actual behavior
t1
is true, and t2
is never.
🙂 Expected behavior
Both, t1
and t2
should be the same and be never
, because {a: string} extends {a: 'id' | 'username'}
is false.
The only difference is that the left value of extends is for t2
an alias, but the same type as in t1
.
Interesting might be that t2
was in v4.1 true
as well, but started to get the right value in v4.2.
Maybe related to https://github.com/microsoft/TypeScript/issues/31295
Issue Analytics
- State:
- Created a year ago
- Comments:5 (4 by maintainers)
Top Results From Across the Web
Conditional types change behaviour if under type alias - Reddit
Conditional types change behaviour if under type alias. I recently wanted to make sure that an array of strings contained all the strings...
Read more >Aliasing and Mutability
List Values Can Be Changed. Unlike the previous types we've worked with, the values in a list can be changed directly, without creating...
Read more >Documentation - Conditional Types - TypeScript
Create types which act like if statements in the type system. ... Conditional types help describe the relation between the types of inputs...
Read more >Typescript: Type alias results in strange type when returning ...
The printing of types in typescript is not something that is well defined and changes frequently based on feedback. In most cases typescript ......
Read more >Type alias, alias template (since C++11) - cppreference.com
It does not introduce a new type and it cannot change the meaning of an existing type name. There is no difference between...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I believe this boils down to an unsound variance check. TS detects
Q<T>
as contravariant, sincekeyof
is contravariant, and thus simplifies the check ofQ<any> extends Q<User>
toUser extends any
, which is obviously true. However,keyof
is not always contravariant; for example:T2
is never because the intermediate type alias causes the instantiation ofQ<A>
, making theextends
use a structural comparison instead of the unsound variance comparison.IIUC #48070, or at least the draft fix that Anders put up, is specific to signatures. I think @tjjfvi nailed it. @ahejlsberg thoughts / triage help?