Skip to content

Commit c0b9fa9

Browse files
committed
Don't defer index types for non-generic substitution types
1 parent 833a8d4 commit c0b9fa9

7 files changed

Lines changed: 171 additions & 0 deletions

src/compiler/checker.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18903,6 +18903,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1890318903
function getIndexType(type: Type, indexFlags = IndexFlags.None): Type {
1890418904
type = getReducedType(type);
1890518905
return isNoInferType(type) ? getNoInferType(getIndexType((type as SubstitutionType).baseType, indexFlags)) :
18906+
type.flags & TypeFlags.Substitution && !isGenericType((type as SubstitutionType).baseType) && !isGenericType((type as SubstitutionType).constraint) ? getUnionType([getIndexType((type as SubstitutionType).baseType, indexFlags), getIndexType((type as SubstitutionType).constraint, indexFlags)]) :
1890618907
shouldDeferIndexType(type, indexFlags) ? getIndexTypeForGenericType(type as InstantiableType | UnionOrIntersectionType, indexFlags) :
1890718908
type.flags & TypeFlags.Union ? getIntersectionType(map((type as UnionType).types, t => getIndexType(t, indexFlags))) :
1890818909
type.flags & TypeFlags.Intersection ? getUnionType(map((type as IntersectionType).types, t => getIndexType(t, indexFlags))) :
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//// [tests/cases/compiler/substitutionTypeNonGenericIndexType1.ts] ////
2+
3+
=== substitutionTypeNonGenericIndexType1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/61728
5+
6+
type BasicConditional<T> = keyof T extends any
7+
>BasicConditional : Symbol(BasicConditional, Decl(substitutionTypeNonGenericIndexType1.ts, 0, 0))
8+
>T : Symbol(T, Decl(substitutionTypeNonGenericIndexType1.ts, 2, 22))
9+
>T : Symbol(T, Decl(substitutionTypeNonGenericIndexType1.ts, 2, 22))
10+
11+
? true
12+
: false;
13+
14+
type Config = { rejectClose: true };
15+
>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType1.ts, 4, 10))
16+
>rejectClose : Symbol(rejectClose, Decl(substitutionTypeNonGenericIndexType1.ts, 6, 15))
17+
18+
type Test =
19+
>Test : Symbol(Test, Decl(substitutionTypeNonGenericIndexType1.ts, 6, 36))
20+
21+
Config extends {}
22+
>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType1.ts, 4, 10))
23+
24+
? {
25+
rejectClose: BasicConditional<Config>;
26+
>rejectClose : Symbol(rejectClose, Decl(substitutionTypeNonGenericIndexType1.ts, 9, 7))
27+
>BasicConditional : Symbol(BasicConditional, Decl(substitutionTypeNonGenericIndexType1.ts, 0, 0))
28+
>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType1.ts, 4, 10))
29+
}
30+
: never;
31+
32+
type RejectClose = Test["rejectClose"];
33+
>RejectClose : Symbol(RejectClose, Decl(substitutionTypeNonGenericIndexType1.ts, 12, 12))
34+
>Test : Symbol(Test, Decl(substitutionTypeNonGenericIndexType1.ts, 6, 36))
35+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//// [tests/cases/compiler/substitutionTypeNonGenericIndexType1.ts] ////
2+
3+
=== substitutionTypeNonGenericIndexType1.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/61728
5+
6+
type BasicConditional<T> = keyof T extends any
7+
>BasicConditional : BasicConditional<T>
8+
> : ^^^^^^^^^^^^^^^^^^^
9+
10+
? true
11+
>true : true
12+
> : ^^^^
13+
14+
: false;
15+
>false : false
16+
> : ^^^^^
17+
18+
type Config = { rejectClose: true };
19+
>Config : Config
20+
> : ^^^^^^
21+
>rejectClose : true
22+
> : ^^^^
23+
>true : true
24+
> : ^^^^
25+
26+
type Test =
27+
>Test : { rejectClose: BasicConditional<Config>; }
28+
> : ^^^^^^^^^^^^^^^ ^^^
29+
30+
Config extends {}
31+
? {
32+
rejectClose: BasicConditional<Config>;
33+
>rejectClose : true
34+
> : ^^^^
35+
}
36+
: never;
37+
38+
type RejectClose = Test["rejectClose"];
39+
>RejectClose : true
40+
> : ^^^^
41+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//// [tests/cases/compiler/substitutionTypeNonGenericIndexType2.ts] ////
2+
3+
=== substitutionTypeNonGenericIndexType2.ts ===
4+
type BasicConditional<T> = keyof T extends infer R ? R : never;
5+
>BasicConditional : Symbol(BasicConditional, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 0))
6+
>T : Symbol(T, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 22))
7+
>T : Symbol(T, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 22))
8+
>R : Symbol(R, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 48))
9+
>R : Symbol(R, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 48))
10+
11+
type Config = { rejectClose: true };
12+
>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 63))
13+
>rejectClose : Symbol(rejectClose, Decl(substitutionTypeNonGenericIndexType2.ts, 2, 15))
14+
15+
type Test = Config extends {}
16+
>Test : Symbol(Test, Decl(substitutionTypeNonGenericIndexType2.ts, 2, 36))
17+
>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 63))
18+
19+
? {
20+
rejectClose: BasicConditional<Config>;
21+
>rejectClose : Symbol(rejectClose, Decl(substitutionTypeNonGenericIndexType2.ts, 5, 5))
22+
>BasicConditional : Symbol(BasicConditional, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 0))
23+
>Config : Symbol(Config, Decl(substitutionTypeNonGenericIndexType2.ts, 0, 63))
24+
}
25+
: never;
26+
27+
const test: Test["rejectClose"] = "rejectClose";
28+
>test : Symbol(test, Decl(substitutionTypeNonGenericIndexType2.ts, 10, 5))
29+
>Test : Symbol(Test, Decl(substitutionTypeNonGenericIndexType2.ts, 2, 36))
30+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//// [tests/cases/compiler/substitutionTypeNonGenericIndexType2.ts] ////
2+
3+
=== substitutionTypeNonGenericIndexType2.ts ===
4+
type BasicConditional<T> = keyof T extends infer R ? R : never;
5+
>BasicConditional : BasicConditional<T>
6+
> : ^^^^^^^^^^^^^^^^^^^
7+
8+
type Config = { rejectClose: true };
9+
>Config : Config
10+
> : ^^^^^^
11+
>rejectClose : true
12+
> : ^^^^
13+
>true : true
14+
> : ^^^^
15+
16+
type Test = Config extends {}
17+
>Test : { rejectClose: BasicConditional<Config>; }
18+
> : ^^^^^^^^^^^^^^^ ^^^
19+
20+
? {
21+
rejectClose: BasicConditional<Config>;
22+
>rejectClose : "rejectClose"
23+
> : ^^^^^^^^^^^^^
24+
}
25+
: never;
26+
27+
const test: Test["rejectClose"] = "rejectClose";
28+
>test : "rejectClose"
29+
> : ^^^^^^^^^^^^^
30+
>"rejectClose" : "rejectClose"
31+
> : ^^^^^^^^^^^^^
32+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// https://github.com/microsoft/TypeScript/issues/61728
5+
6+
type BasicConditional<T> = keyof T extends any
7+
? true
8+
: false;
9+
10+
type Config = { rejectClose: true };
11+
type Test =
12+
Config extends {}
13+
? {
14+
rejectClose: BasicConditional<Config>;
15+
}
16+
: never;
17+
18+
type RejectClose = Test["rejectClose"];
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
type BasicConditional<T> = keyof T extends infer R ? R : never;
5+
6+
type Config = { rejectClose: true };
7+
8+
type Test = Config extends {}
9+
? {
10+
rejectClose: BasicConditional<Config>;
11+
}
12+
: never;
13+
14+
const test: Test["rejectClose"] = "rejectClose";

0 commit comments

Comments
 (0)