Skip to content

Commit 03c11c8

Browse files
authored
Add missing getReducedType call in getConditionalTypeInstantiation (microsoft#48061)
1 parent 41b981c commit 03c11c8

File tree

5 files changed

+161
-1
lines changed

5 files changed

+161
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16854,7 +16854,7 @@ namespace ts {
1685416854
// distributive conditional type T extends U ? X : Y is instantiated with A | B for T, the
1685516855
// result is (A extends U ? X : Y) | (B extends U ? X : Y).
1685616856
result = distributionType && checkType !== distributionType && distributionType.flags & (TypeFlags.Union | TypeFlags.Never) ?
16857-
mapTypeWithAlias(distributionType, t => getConditionalType(root, prependTypeMapping(checkType, t, newMapper)), aliasSymbol, aliasTypeArguments) :
16857+
mapTypeWithAlias(getReducedType(distributionType), t => getConditionalType(root, prependTypeMapping(checkType, t, newMapper)), aliasSymbol, aliasTypeArguments) :
1685816858
getConditionalType(root, newMapper, aliasSymbol, aliasTypeArguments);
1685916859
root.instantiations!.set(id, result);
1686016860
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//// [objectAssignLikeNonUnionResult.ts]
2+
interface Interface {
3+
field: number;
4+
}
5+
const defaultValue: Interface = { field: 1 };
6+
7+
declare function assign<T, U>(target: T, source: U): T & U;
8+
9+
// Displayed type: Interface & { field: number }
10+
// Underlying type: Something else...
11+
const data1 = assign(defaultValue, Date.now() > 3 ? { field: 2 } : {});
12+
13+
type ExtractRawComponent<T> = T extends { __raw: infer C } ? [L1: T, L2: C] : [R1: T];
14+
type t1 = ExtractRawComponent<typeof data1>;
15+
16+
// ???
17+
type Explode<T> = T extends { x: infer A } ? [A] : 'X';
18+
// 'X' | [unknown] -- why?
19+
type e1 = Explode<typeof data1>;
20+
21+
//// [objectAssignLikeNonUnionResult.js]
22+
var defaultValue = { field: 1 };
23+
// Displayed type: Interface & { field: number }
24+
// Underlying type: Something else...
25+
var data1 = assign(defaultValue, Date.now() > 3 ? { field: 2 } : {});
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
=== tests/cases/compiler/objectAssignLikeNonUnionResult.ts ===
2+
interface Interface {
3+
>Interface : Symbol(Interface, Decl(objectAssignLikeNonUnionResult.ts, 0, 0))
4+
5+
field: number;
6+
>field : Symbol(Interface.field, Decl(objectAssignLikeNonUnionResult.ts, 0, 21))
7+
}
8+
const defaultValue: Interface = { field: 1 };
9+
>defaultValue : Symbol(defaultValue, Decl(objectAssignLikeNonUnionResult.ts, 3, 5))
10+
>Interface : Symbol(Interface, Decl(objectAssignLikeNonUnionResult.ts, 0, 0))
11+
>field : Symbol(field, Decl(objectAssignLikeNonUnionResult.ts, 3, 33))
12+
13+
declare function assign<T, U>(target: T, source: U): T & U;
14+
>assign : Symbol(assign, Decl(objectAssignLikeNonUnionResult.ts, 3, 45))
15+
>T : Symbol(T, Decl(objectAssignLikeNonUnionResult.ts, 5, 24))
16+
>U : Symbol(U, Decl(objectAssignLikeNonUnionResult.ts, 5, 26))
17+
>target : Symbol(target, Decl(objectAssignLikeNonUnionResult.ts, 5, 30))
18+
>T : Symbol(T, Decl(objectAssignLikeNonUnionResult.ts, 5, 24))
19+
>source : Symbol(source, Decl(objectAssignLikeNonUnionResult.ts, 5, 40))
20+
>U : Symbol(U, Decl(objectAssignLikeNonUnionResult.ts, 5, 26))
21+
>T : Symbol(T, Decl(objectAssignLikeNonUnionResult.ts, 5, 24))
22+
>U : Symbol(U, Decl(objectAssignLikeNonUnionResult.ts, 5, 26))
23+
24+
// Displayed type: Interface & { field: number }
25+
// Underlying type: Something else...
26+
const data1 = assign(defaultValue, Date.now() > 3 ? { field: 2 } : {});
27+
>data1 : Symbol(data1, Decl(objectAssignLikeNonUnionResult.ts, 9, 5))
28+
>assign : Symbol(assign, Decl(objectAssignLikeNonUnionResult.ts, 3, 45))
29+
>defaultValue : Symbol(defaultValue, Decl(objectAssignLikeNonUnionResult.ts, 3, 5))
30+
>Date.now : Symbol(DateConstructor.now, Decl(lib.es5.d.ts, --, --))
31+
>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --))
32+
>now : Symbol(DateConstructor.now, Decl(lib.es5.d.ts, --, --))
33+
>field : Symbol(field, Decl(objectAssignLikeNonUnionResult.ts, 9, 53))
34+
35+
type ExtractRawComponent<T> = T extends { __raw: infer C } ? [L1: T, L2: C] : [R1: T];
36+
>ExtractRawComponent : Symbol(ExtractRawComponent, Decl(objectAssignLikeNonUnionResult.ts, 9, 71))
37+
>T : Symbol(T, Decl(objectAssignLikeNonUnionResult.ts, 11, 25))
38+
>T : Symbol(T, Decl(objectAssignLikeNonUnionResult.ts, 11, 25))
39+
>__raw : Symbol(__raw, Decl(objectAssignLikeNonUnionResult.ts, 11, 41))
40+
>C : Symbol(C, Decl(objectAssignLikeNonUnionResult.ts, 11, 54))
41+
>T : Symbol(T, Decl(objectAssignLikeNonUnionResult.ts, 11, 25))
42+
>C : Symbol(C, Decl(objectAssignLikeNonUnionResult.ts, 11, 54))
43+
>T : Symbol(T, Decl(objectAssignLikeNonUnionResult.ts, 11, 25))
44+
45+
type t1 = ExtractRawComponent<typeof data1>;
46+
>t1 : Symbol(t1, Decl(objectAssignLikeNonUnionResult.ts, 11, 86))
47+
>ExtractRawComponent : Symbol(ExtractRawComponent, Decl(objectAssignLikeNonUnionResult.ts, 9, 71))
48+
>data1 : Symbol(data1, Decl(objectAssignLikeNonUnionResult.ts, 9, 5))
49+
50+
// ???
51+
type Explode<T> = T extends { x: infer A } ? [A] : 'X';
52+
>Explode : Symbol(Explode, Decl(objectAssignLikeNonUnionResult.ts, 12, 44))
53+
>T : Symbol(T, Decl(objectAssignLikeNonUnionResult.ts, 15, 13))
54+
>T : Symbol(T, Decl(objectAssignLikeNonUnionResult.ts, 15, 13))
55+
>x : Symbol(x, Decl(objectAssignLikeNonUnionResult.ts, 15, 29))
56+
>A : Symbol(A, Decl(objectAssignLikeNonUnionResult.ts, 15, 38))
57+
>A : Symbol(A, Decl(objectAssignLikeNonUnionResult.ts, 15, 38))
58+
59+
// 'X' | [unknown] -- why?
60+
type e1 = Explode<typeof data1>;
61+
>e1 : Symbol(e1, Decl(objectAssignLikeNonUnionResult.ts, 15, 55))
62+
>Explode : Symbol(Explode, Decl(objectAssignLikeNonUnionResult.ts, 12, 44))
63+
>data1 : Symbol(data1, Decl(objectAssignLikeNonUnionResult.ts, 9, 5))
64+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
=== tests/cases/compiler/objectAssignLikeNonUnionResult.ts ===
2+
interface Interface {
3+
field: number;
4+
>field : number
5+
}
6+
const defaultValue: Interface = { field: 1 };
7+
>defaultValue : Interface
8+
>{ field: 1 } : { field: number; }
9+
>field : number
10+
>1 : 1
11+
12+
declare function assign<T, U>(target: T, source: U): T & U;
13+
>assign : <T, U>(target: T, source: U) => T & U
14+
>target : T
15+
>source : U
16+
17+
// Displayed type: Interface & { field: number }
18+
// Underlying type: Something else...
19+
const data1 = assign(defaultValue, Date.now() > 3 ? { field: 2 } : {});
20+
>data1 : Interface & { field: number; }
21+
>assign(defaultValue, Date.now() > 3 ? { field: 2 } : {}) : Interface & { field: number; }
22+
>assign : <T, U>(target: T, source: U) => T & U
23+
>defaultValue : Interface
24+
>Date.now() > 3 ? { field: 2 } : {} : { field: number; } | {}
25+
>Date.now() > 3 : boolean
26+
>Date.now() : number
27+
>Date.now : () => number
28+
>Date : DateConstructor
29+
>now : () => number
30+
>3 : 3
31+
>{ field: 2 } : { field: number; }
32+
>field : number
33+
>2 : 2
34+
>{} : {}
35+
36+
type ExtractRawComponent<T> = T extends { __raw: infer C } ? [L1: T, L2: C] : [R1: T];
37+
>ExtractRawComponent : ExtractRawComponent<T>
38+
>__raw : C
39+
40+
type t1 = ExtractRawComponent<typeof data1>;
41+
>t1 : [R1: Interface & { field: number; }]
42+
>data1 : Interface & { field: number; }
43+
44+
// ???
45+
type Explode<T> = T extends { x: infer A } ? [A] : 'X';
46+
>Explode : Explode<T>
47+
>x : A
48+
49+
// 'X' | [unknown] -- why?
50+
type e1 = Explode<typeof data1>;
51+
>e1 : "X"
52+
>data1 : Interface & { field: number; }
53+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
interface Interface {
2+
field: number;
3+
}
4+
const defaultValue: Interface = { field: 1 };
5+
6+
declare function assign<T, U>(target: T, source: U): T & U;
7+
8+
// Displayed type: Interface & { field: number }
9+
// Underlying type: Something else...
10+
const data1 = assign(defaultValue, Date.now() > 3 ? { field: 2 } : {});
11+
12+
type ExtractRawComponent<T> = T extends { __raw: infer C } ? [L1: T, L2: C] : [R1: T];
13+
type t1 = ExtractRawComponent<typeof data1>;
14+
15+
// ???
16+
type Explode<T> = T extends { x: infer A } ? [A] : 'X';
17+
// 'X' | [unknown] -- why?
18+
type e1 = Explode<typeof data1>;

0 commit comments

Comments
 (0)