microsoft / microsoft/TypeScript
`extends any ?` may return right hand in conditional types
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
TypeScript Version: 4.0.5
Search Terms:
- type inference
- extends any
- conditional types
- right hand
Expected behavior:
type D1 = X1 <O1> returns false.
Actual behavior:
In the code below, type D1 = X1<O1> seems to return false, but it actually returns true.
If you change the seemingly irrelevant right-hand type in extends any ? written for union distribution to undefined, it will behave as intended.
Related Issues:
Code
type X1<T> = IfEq<
AllKeys1<T>,
keyof T,
true,
false
>;
type X2<T> = IfEq<
AllKeys2<T>,
keyof T,
true,
false
>;
type IfEq<X, Y, T, E> = [X] extends [Y] ? ([Y] extends [X] ? T : E) : E;
// AllKeys<{ x: ... } | { x: ...; y: ... }> -> "x" | ("x" | "y") -> "x" | "y"
type AllKeys1<O extends Object> = O extends any ? keyof O : never;
type AllKeys2<O extends Object> = O extends any ? keyof O : undefined;
type O1 = { x: string; y: number } | { x: boolean; z: number }
type A1 = AllKeys1<O1> // "x" | "y" | "z"
type A2 = AllKeys2<O1> // "x" | "y" | "z"
type B = keyof O1 // "x"
type C1 = IfEq<A1, B, true, false> // false
type C2 = IfEq<A2, B, true, false> // false
type D1 = X1<O1> // true ???
type D2 = X2<O1> // false
type O2 = { x: string; y: number } | { x: boolean; y: Object }
type E1 = X1<O2> // true
type E2 = X2<O2> // true
Output
"use strict";
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": 2,
"target": "ES2017",
"jsx": "React",
"module": "ESNext"
}
}
Playground Link: Provided
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the provided Playground reproduction using TypeScript 4.0.5 and compare the conditional-type results for D1, D2, E1, and E2. Trace the compiler's handling of distributive conditional types and verify that the reported expected and actual results are resolved consistently without changing the other cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100