Skip to content

Commit 3df8c50

Browse files
committed
Changed processing for IndexAccess to be done in sourceFlags & TypeFlags.TypeVariable section
1 parent 0f6bc92 commit 3df8c50

10 files changed

+181
-46
lines changed

src/compiler/checker.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13508,12 +13508,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1350813508
// we substitute an instantiation of E where P is replaced with X.
1350913509
return substituteIndexedMappedType(type.objectType as MappedType, type.indexType);
1351013510
}
13511-
const indexType = type.indexType;
13512-
let indexConstraint = getSimplifiedTypeOrConstraint(indexType);
13513-
if (indexConstraint && indexConstraint.flags & TypeFlags.Index) {
13514-
const constraint = getBaseConstraintOfType((indexConstraint as IndexType).type);
13515-
indexConstraint = constraint && constraint !== noConstraintType ? getIndexType(constraint) : keyofConstraintType;
13516-
}
13511+
const indexConstraint = getSimplifiedTypeOrConstraint(type.indexType);
1351713512
if (indexConstraint && indexConstraint !== type.indexType) {
1351813513
const indexedAccess = getIndexedAccessTypeOrUndefined(type.objectType, indexConstraint, type.accessFlags);
1351913514
if (indexedAccess) {
@@ -21471,6 +21466,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2147121466
else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && constraint !== unknownType && !(targetFlags & sourceFlags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) {
2147221467
return result;
2147321468
}
21469+
if (sourceFlags & TypeFlags.IndexedAccess) {
21470+
const indexType = (source as IndexedAccessType).indexType;
21471+
if (indexType.flags & TypeFlags.Index) {
21472+
const a = getBaseConstraintOfType((indexType as IndexType).type);
21473+
const indexConstraint = a && a !== noConstraintType ? getIndexType(a) : keyofConstraintType;
21474+
const constraint = getIndexedAccessType((source as IndexedAccessType).objectType, indexConstraint);
21475+
if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) {
21476+
return result;
21477+
}
21478+
}
21479+
}
2147421480
if (isMappedTypeGenericIndexedAccess(source)) {
2147521481
// For an indexed access type { [P in K]: E}[X], above we have already explored an instantiation of E with X
2147621482
// substituted for P. We also want to explore type { [P in K]: E }[C], where C is the constraint of X.
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
tests/cases/compiler/constraintWithIndexedAccess.ts(27,13): error TS2300: Duplicate identifier 'TypeGeneric'.
2+
tests/cases/compiler/constraintWithIndexedAccess.ts(28,13): error TS2300: Duplicate identifier 'TypeGeneric'.
3+
tests/cases/compiler/constraintWithIndexedAccess.ts(28,101): error TS2344: Type 'DataFetchFns[T][T]' does not satisfy the constraint '(...args: any) => any'.
4+
Type 'DataFetchFns[T]["Boat"] | DataFetchFns[T]["Plane"]' is not assignable to type '(...args: any) => any'.
5+
Type 'DataFetchFns[T]["Boat"]' is not assignable to type '(...args: any) => any'.
6+
tests/cases/compiler/constraintWithIndexedAccess.ts(28,101): error TS2536: Type 'T' cannot be used to index type 'DataFetchFns[T]'.
7+
tests/cases/compiler/constraintWithIndexedAccess.ts(29,13): error TS2300: Duplicate identifier 'TypeGeneric'.
8+
tests/cases/compiler/constraintWithIndexedAccess.ts(29,101): error TS2536: Type 'F' cannot be used to index type 'DataFetchFns'.
9+
tests/cases/compiler/constraintWithIndexedAccess.ts(29,101): error TS2344: Type 'DataFetchFns[F][F]' does not satisfy the constraint '(...args: any) => any'.
10+
Type 'DataFetchFns[F][keyof DataFetchFns[T]]' is not assignable to type '(...args: any) => any'.
11+
Type 'DataFetchFns[F][string] | DataFetchFns[F][number] | DataFetchFns[F][symbol]' is not assignable to type '(...args: any) => any'.
12+
Type 'DataFetchFns[F][string]' is not assignable to type '(...args: any) => any'.
13+
Type 'DataFetchFns[keyof DataFetchFns[T]][string]' is not assignable to type '(...args: any) => any'.
14+
tests/cases/compiler/constraintWithIndexedAccess.ts(29,101): error TS2536: Type 'F' cannot be used to index type 'DataFetchFns[F]'.
15+
16+
17+
==== tests/cases/compiler/constraintWithIndexedAccess.ts (8 errors) ====
18+
// #52399
19+
type DataFetchFns = {
20+
Boat: {
21+
requiresLicense: (id: string) => boolean;
22+
maxGroundSpeed: (id: string) => number;
23+
description: (id: string) => string;
24+
displacement: (id: string) => number;
25+
name: (id: string) => string;
26+
};
27+
Plane: {
28+
requiresLicense: (id: string) => boolean;
29+
maxGroundSpeed: (id: string) => number;
30+
maxTakeoffWeight: (id: string) => number;
31+
maxCruisingAltitude: (id: string) => number;
32+
name: (id: string) => string;
33+
}
34+
}
35+
export type NoTypeParamBoatRequired<F extends keyof DataFetchFns['Boat']> = ReturnType<DataFetchFns['Boat'][F]>;
36+
type TypeHardcodedAsParameterWithoutReturnType<T extends 'Boat', F extends keyof DataFetchFns[T]> = DataFetchFns[T][F];
37+
export type allAreFunctionsAsExpected = TypeHardcodedAsParameterWithoutReturnType<'Boat', keyof DataFetchFns['Boat']>;
38+
export type returnTypeOfFunctions = ReturnType<allAreFunctionsAsExpected>; //string | number | boolean as expected
39+
export type SucceedingCombo = ReturnType<TypeHardcodedAsParameterWithoutReturnType<'Boat', keyof DataFetchFns['Boat']>>;
40+
export type FailingCombo<T extends 'Boat', F extends keyof DataFetchFns[T]> = ReturnType<TypeHardcodedAsParameterWithoutReturnType<T,F>>;
41+
export type TypeHardcodedAsParameter<T extends 'Boat', F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[T][F]>;
42+
type VehicleSelector<T extends keyof DataFetchFns> = DataFetchFns[T];
43+
export type TypeHardcodedAsParameter2<T extends 'Boat', F extends keyof DataFetchFns[T]> = ReturnType<VehicleSelector<T>[F]>;
44+
export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[T][F]>;
45+
~~~~~~~~~~~
46+
!!! error TS2300: Duplicate identifier 'TypeGeneric'.
47+
export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[T][T]>; // error
48+
~~~~~~~~~~~
49+
!!! error TS2300: Duplicate identifier 'TypeGeneric'.
50+
~~~~~~~~~~~~~~~~~~
51+
!!! error TS2344: Type 'DataFetchFns[T][T]' does not satisfy the constraint '(...args: any) => any'.
52+
!!! error TS2344: Type 'DataFetchFns[T]["Boat"] | DataFetchFns[T]["Plane"]' is not assignable to type '(...args: any) => any'.
53+
!!! error TS2344: Type 'DataFetchFns[T]["Boat"]' is not assignable to type '(...args: any) => any'.
54+
~~~~~~~~~~~~~~~~~~
55+
!!! error TS2536: Type 'T' cannot be used to index type 'DataFetchFns[T]'.
56+
export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[F][F]>; // error
57+
~~~~~~~~~~~
58+
!!! error TS2300: Duplicate identifier 'TypeGeneric'.
59+
~~~~~~~~~~~~~~~
60+
!!! error TS2536: Type 'F' cannot be used to index type 'DataFetchFns'.
61+
~~~~~~~~~~~~~~~~~~
62+
!!! error TS2344: Type 'DataFetchFns[F][F]' does not satisfy the constraint '(...args: any) => any'.
63+
!!! error TS2344: Type 'DataFetchFns[F][keyof DataFetchFns[T]]' is not assignable to type '(...args: any) => any'.
64+
!!! error TS2344: Type 'DataFetchFns[F][string] | DataFetchFns[F][number] | DataFetchFns[F][symbol]' is not assignable to type '(...args: any) => any'.
65+
!!! error TS2344: Type 'DataFetchFns[F][string]' is not assignable to type '(...args: any) => any'.
66+
!!! error TS2344: Type 'DataFetchFns[keyof DataFetchFns[T]][string]' is not assignable to type '(...args: any) => any'.
67+
~~~~~~~~~~~~~~~~~~
68+
!!! error TS2536: Type 'F' cannot be used to index type 'DataFetchFns[F]'.
69+

tests/baselines/reference/constraintWithIndexedAccess.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ export type TypeHardcodedAsParameter<T extends 'Boat', F extends keyof DataFetch
2626
type VehicleSelector<T extends keyof DataFetchFns> = DataFetchFns[T];
2727
export type TypeHardcodedAsParameter2<T extends 'Boat', F extends keyof DataFetchFns[T]> = ReturnType<VehicleSelector<T>[F]>;
2828
export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[T][F]>;
29+
export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[T][T]>; // error
30+
export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[F][F]>; // error
2931

3032

3133
//// [constraintWithIndexedAccess.js]

tests/baselines/reference/constraintWithIndexedAccess.symbols

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,27 @@ export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchF
137137
>T : Symbol(T, Decl(constraintWithIndexedAccess.ts, 26, 24))
138138
>F : Symbol(F, Decl(constraintWithIndexedAccess.ts, 26, 53))
139139

140+
export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[T][T]>; // error
141+
>TypeGeneric : Symbol(TypeGeneric, Decl(constraintWithIndexedAccess.ts, 26, 120))
142+
>T : Symbol(T, Decl(constraintWithIndexedAccess.ts, 27, 24))
143+
>DataFetchFns : Symbol(DataFetchFns, Decl(constraintWithIndexedAccess.ts, 0, 0))
144+
>F : Symbol(F, Decl(constraintWithIndexedAccess.ts, 27, 53))
145+
>DataFetchFns : Symbol(DataFetchFns, Decl(constraintWithIndexedAccess.ts, 0, 0))
146+
>T : Symbol(T, Decl(constraintWithIndexedAccess.ts, 27, 24))
147+
>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --))
148+
>DataFetchFns : Symbol(DataFetchFns, Decl(constraintWithIndexedAccess.ts, 0, 0))
149+
>T : Symbol(T, Decl(constraintWithIndexedAccess.ts, 27, 24))
150+
>T : Symbol(T, Decl(constraintWithIndexedAccess.ts, 27, 24))
151+
152+
export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[F][F]>; // error
153+
>TypeGeneric : Symbol(TypeGeneric, Decl(constraintWithIndexedAccess.ts, 27, 120))
154+
>T : Symbol(T, Decl(constraintWithIndexedAccess.ts, 28, 24))
155+
>DataFetchFns : Symbol(DataFetchFns, Decl(constraintWithIndexedAccess.ts, 0, 0))
156+
>F : Symbol(F, Decl(constraintWithIndexedAccess.ts, 28, 53))
157+
>DataFetchFns : Symbol(DataFetchFns, Decl(constraintWithIndexedAccess.ts, 0, 0))
158+
>T : Symbol(T, Decl(constraintWithIndexedAccess.ts, 28, 24))
159+
>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --))
160+
>DataFetchFns : Symbol(DataFetchFns, Decl(constraintWithIndexedAccess.ts, 0, 0))
161+
>F : Symbol(F, Decl(constraintWithIndexedAccess.ts, 28, 53))
162+
>F : Symbol(F, Decl(constraintWithIndexedAccess.ts, 28, 53))
163+

tests/baselines/reference/constraintWithIndexedAccess.types

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,9 @@ export type TypeHardcodedAsParameter2<T extends 'Boat', F extends keyof DataFetc
8181
export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[T][F]>;
8282
>TypeGeneric : TypeGeneric<T, F>
8383

84+
export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[T][T]>; // error
85+
>TypeGeneric : import("tests/cases/compiler/constraintWithIndexedAccess").TypeGeneric<T, F>
86+
87+
export type TypeGeneric<T extends keyof DataFetchFns, F extends keyof DataFetchFns[T]> = ReturnType<DataFetchFns[F][F]>; // error
88+
>TypeGeneric : import("tests/cases/compiler/constraintWithIndexedAccess").TypeGeneric<T, F>
89+

tests/baselines/reference/deepComparisons.errors.txt

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
tests/cases/compiler/deepComparisons.ts(2,9): error TS2322: Type 'T' is not assignable to type 'Extract<T, string>'.
22
tests/cases/compiler/deepComparisons.ts(3,9): error TS2322: Type 'T[K1]' is not assignable to type 'Extract<T[K1], string>'.
3-
Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'Extract<T[K1], string>'.
4-
Type 'T[string]' is not assignable to type 'Extract<T[K1], string>'.
3+
Type 'T[keyof T]' is not assignable to type 'Extract<T[K1], string>'.
4+
Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'Extract<T[K1], string>'.
5+
Type 'T[string]' is not assignable to type 'Extract<T[K1], string>'.
56
tests/cases/compiler/deepComparisons.ts(4,9): error TS2322: Type 'T[K1][K2]' is not assignable to type 'Extract<T[K1][K2], string>'.
6-
Type 'T[K1][string] | T[K1][number] | T[K1][symbol]' is not assignable to type 'Extract<T[K1][K2], string>'.
7-
Type 'T[K1][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
8-
Type 'T[string][string] | T[number][string] | T[symbol][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
9-
Type 'T[string][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
7+
Type 'T[K1][keyof T[K1]]' is not assignable to type 'Extract<T[K1][K2], string>'.
8+
Type 'T[K1][string] | T[K1][number] | T[K1][symbol]' is not assignable to type 'Extract<T[K1][K2], string>'.
9+
Type 'T[K1][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
10+
Type 'T[keyof T][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
11+
Type 'T[string][string] | T[number][string] | T[symbol][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
12+
Type 'T[string][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
1013

1114

1215
==== tests/cases/compiler/deepComparisons.ts (3 errors) ====
@@ -17,15 +20,18 @@ tests/cases/compiler/deepComparisons.ts(4,9): error TS2322: Type 'T[K1][K2]' is
1720
let v2: Extract<T[K1], string> = 0 as any as T[K1]; // Error
1821
~~
1922
!!! error TS2322: Type 'T[K1]' is not assignable to type 'Extract<T[K1], string>'.
20-
!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'Extract<T[K1], string>'.
21-
!!! error TS2322: Type 'T[string]' is not assignable to type 'Extract<T[K1], string>'.
23+
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'Extract<T[K1], string>'.
24+
!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'Extract<T[K1], string>'.
25+
!!! error TS2322: Type 'T[string]' is not assignable to type 'Extract<T[K1], string>'.
2226
let v3: Extract<T[K1][K2], string> = 0 as any as T[K1][K2]; // No error
2327
~~
2428
!!! error TS2322: Type 'T[K1][K2]' is not assignable to type 'Extract<T[K1][K2], string>'.
25-
!!! error TS2322: Type 'T[K1][string] | T[K1][number] | T[K1][symbol]' is not assignable to type 'Extract<T[K1][K2], string>'.
26-
!!! error TS2322: Type 'T[K1][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
27-
!!! error TS2322: Type 'T[string][string] | T[number][string] | T[symbol][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
28-
!!! error TS2322: Type 'T[string][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
29+
!!! error TS2322: Type 'T[K1][keyof T[K1]]' is not assignable to type 'Extract<T[K1][K2], string>'.
30+
!!! error TS2322: Type 'T[K1][string] | T[K1][number] | T[K1][symbol]' is not assignable to type 'Extract<T[K1][K2], string>'.
31+
!!! error TS2322: Type 'T[K1][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
32+
!!! error TS2322: Type 'T[keyof T][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
33+
!!! error TS2322: Type 'T[string][string] | T[number][string] | T[symbol][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
34+
!!! error TS2322: Type 'T[string][string]' is not assignable to type 'Extract<T[K1][K2], string>'.
2935
}
3036

3137
type Foo<T> = { x: Foo<T> };

tests/baselines/reference/keyofAndIndexedAccess.errors.txt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(205,24): error TS23
22
Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'object'.
33
Type 'T[string]' is not assignable to type 'object'.
44
tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(211,24): error TS2322: Type 'T[K]' is not assignable to type 'object'.
5-
Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'object'.
6-
Type 'T[string]' is not assignable to type 'object'.
5+
Type 'T[keyof T]' is not assignable to type 'object'.
6+
Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'object'.
7+
Type 'T[string]' is not assignable to type 'object'.
78
tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(316,5): error TS2322: Type 'T' is not assignable to type '{}'.
89
tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(317,5): error TS2322: Type 'T[keyof T]' is not assignable to type '{}'.
910
Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'.
1011
Type 'T[string]' is not assignable to type '{}'.
1112
tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(318,5): error TS2322: Type 'T[K]' is not assignable to type '{}'.
12-
Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'.
13-
Type 'T[string]' is not assignable to type '{}'.
13+
Type 'T[keyof T]' is not assignable to type '{}'.
1414

1515

1616
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts (5 errors) ====
@@ -231,8 +231,9 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(318,5): error TS232
231231
const b = "foo" in obj[key];
232232
~~~~~~~~
233233
!!! error TS2322: Type 'T[K]' is not assignable to type 'object'.
234-
!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'object'.
235-
!!! error TS2322: Type 'T[string]' is not assignable to type 'object'.
234+
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'object'.
235+
!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'object'.
236+
!!! error TS2322: Type 'T[string]' is not assignable to type 'object'.
236237
}
237238

238239
function f60<T>(source: T, target: T) {
@@ -349,8 +350,7 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts(318,5): error TS232
349350
a = z;
350351
~
351352
!!! error TS2322: Type 'T[K]' is not assignable to type '{}'.
352-
!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type '{}'.
353-
!!! error TS2322: Type 'T[string]' is not assignable to type '{}'.
353+
!!! error TS2322: Type 'T[keyof T]' is not assignable to type '{}'.
354354
}
355355

356356
function f92<T, K extends keyof T>(x: T, y: T[keyof T], z: T[K]) {

0 commit comments

Comments
 (0)