diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fd6a033653ac0..8504074080ae5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6351,7 +6351,7 @@ namespace ts { return getObjectFlags(type) & ObjectFlags.Mapped && !!(type).declaration.questionToken; } - function isGenericMappedType(type: Type) { + function isGenericMappedType(type: Type): type is MappedType { return getObjectFlags(type) & ObjectFlags.Mapped && isGenericIndexType(getConstraintTypeFromMappedType(type)); } @@ -6463,12 +6463,17 @@ namespace ts { } function getConstraintOfIndexedAccess(type: IndexedAccessType) { - const transformed = getTransformedIndexedAccessType(type); + const transformed = getSimplifiedIndexedAccessType(type); if (transformed) { return transformed; } const baseObjectType = getBaseConstraintOfType(type.objectType); const baseIndexType = getBaseConstraintOfType(type.indexType); + if (baseIndexType === stringType && !getIndexInfoOfType(baseObjectType || type.objectType, IndexKind.String)) { + // getIndexedAccessType returns `any` for X[string] where X doesn't have an index signature. + // to avoid this, return `undefined`. + return undefined; + } return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined; } @@ -6518,8 +6523,9 @@ namespace ts { function computeBaseConstraint(t: Type): Type { if (t.flags & TypeFlags.TypeParameter) { const constraint = getConstraintFromTypeParameter(t); - return (t).isThisType ? constraint : - constraint ? getBaseConstraint(constraint) : undefined; + return (t as TypeParameter).isThisType || !constraint ? + constraint : + getBaseConstraint(constraint); } if (t.flags & TypeFlags.UnionOrIntersection) { const types = (t).types; @@ -6538,7 +6544,7 @@ namespace ts { return stringType; } if (t.flags & TypeFlags.IndexedAccess) { - const transformed = getTransformedIndexedAccessType(t); + const transformed = getSimplifiedIndexedAccessType(t); if (transformed) { return getBaseConstraint(transformed); } @@ -8350,7 +8356,7 @@ namespace ts { // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return // undefined if no transformation is possible. - function getTransformedIndexedAccessType(type: IndexedAccessType): Type { + function getSimplifiedIndexedAccessType(type: IndexedAccessType): Type { const objectType = type.objectType; // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a @@ -8376,14 +8382,24 @@ namespace ts { // that substitutes the index type for P. For example, for an index access { [P in K]: Box }[X], we // construct the type Box. if (isGenericMappedType(objectType)) { - const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]); - const objectTypeMapper = (objectType).mapper; - const templateMapper = objectTypeMapper ? combineTypeMappers(objectTypeMapper, mapper) : mapper; - return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); + return substituteIndexedMappedType(objectType, type); + } + if (objectType.flags & TypeFlags.TypeParameter) { + const constraint = getConstraintFromTypeParameter(objectType as TypeParameter); + if (constraint && isGenericMappedType(constraint)) { + return substituteIndexedMappedType(constraint, type); + } } return undefined; } + function substituteIndexedMappedType(objectType: MappedType, type: IndexedAccessType) { + const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]); + const objectTypeMapper = (objectType).mapper; + const templateMapper = objectTypeMapper ? combineTypeMappers(objectTypeMapper, mapper) : mapper; + return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); + } + function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode): Type { // If the index type is generic, or if the object type is generic and doesn't originate in an expression, // we are performing a higher-order index access where we cannot meaningfully access the properties of the @@ -10059,7 +10075,7 @@ namespace ts { } else if (target.flags & TypeFlags.IndexedAccess) { // A type S is related to a type T[K] if S is related to A[K], where K is string-like and - // A is the apparent type of S. + // A is the apparent type of T. const constraint = getConstraintOfIndexedAccess(target); if (constraint) { if (result = isRelatedTo(source, constraint, reportErrors)) { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 918dbbd51c0c0..24c2153c58246 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -893,7 +893,7 @@ namespace ts { export function sum, K extends string>(array: ReadonlyArray, prop: K): number { let result = 0; for (const v of array) { - // Note: we need the following type assertion because of GH #17069 + // TODO: Remove the following type assertion once the fix for #17069 is merged result += v[prop] as number; } return result; diff --git a/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.js b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.js new file mode 100644 index 0000000000000..1366e242182e4 --- /dev/null +++ b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.js @@ -0,0 +1,27 @@ +//// [additionOperatorWithConstrainedTypeParameter.ts] +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { + n = n + v[k]; + n += v[k]; // += should work the same way +} +function realSum, K extends string>(n: number, vs: T[], k: K) { + for (const v of vs) { + n = n + v[k]; + n += v[k]; + } +} + + +//// [additionOperatorWithConstrainedTypeParameter.js] +// test for #17069 +function sum(n, v, k) { + n = n + v[k]; + n += v[k]; // += should work the same way +} +function realSum(n, vs, k) { + for (var _i = 0, vs_1 = vs; _i < vs_1.length; _i++) { + var v = vs_1[_i]; + n = n + v[k]; + n += v[k]; + } +} diff --git a/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.symbols b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.symbols new file mode 100644 index 0000000000000..e7055c1e38f8d --- /dev/null +++ b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.symbols @@ -0,0 +1,54 @@ +=== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts === +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { +>sum : Symbol(sum, Decl(additionOperatorWithConstrainedTypeParameter.ts, 0, 0)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 13)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 41)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 41)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 70)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 13)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 76)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 41)) + + n = n + v[k]; +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 70)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 76)) + + n += v[k]; // += should work the same way +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 60)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 70)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 1, 76)) +} +function realSum, K extends string>(n: number, vs: T[], k: K) { +>realSum : Symbol(realSum, Decl(additionOperatorWithConstrainedTypeParameter.ts, 4, 1)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 17)) +>Record : Symbol(Record, Decl(lib.d.ts, --, --)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 45)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 45)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>vs : Symbol(vs, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 74)) +>T : Symbol(T, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 17)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 83)) +>K : Symbol(K, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 45)) + + for (const v of vs) { +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 6, 14)) +>vs : Symbol(vs, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 74)) + + n = n + v[k]; +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 6, 14)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 83)) + + n += v[k]; +>n : Symbol(n, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 64)) +>v : Symbol(v, Decl(additionOperatorWithConstrainedTypeParameter.ts, 6, 14)) +>k : Symbol(k, Decl(additionOperatorWithConstrainedTypeParameter.ts, 5, 83)) + } +} + diff --git a/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.types b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.types new file mode 100644 index 0000000000000..d52c77a94fd69 --- /dev/null +++ b/tests/baselines/reference/additionOperatorWithConstrainedTypeParameter.types @@ -0,0 +1,64 @@ +=== tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts === +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { +>sum : , K extends string>(n: number, v: T, k: K) => void +>T : T +>Record : Record +>K : K +>K : K +>n : number +>v : T +>T : T +>k : K +>K : K + + n = n + v[k]; +>n = n + v[k] : number +>n : number +>n + v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K + + n += v[k]; // += should work the same way +>n += v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K +} +function realSum, K extends string>(n: number, vs: T[], k: K) { +>realSum : , K extends string>(n: number, vs: T[], k: K) => void +>T : T +>Record : Record +>K : K +>K : K +>n : number +>vs : T[] +>T : T +>k : K +>K : K + + for (const v of vs) { +>v : T +>vs : T[] + + n = n + v[k]; +>n = n + v[k] : number +>n : number +>n + v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K + + n += v[k]; +>n += v[k] : number +>n : number +>v[k] : T[K] +>v : T +>k : K + } +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index 0634c3419e014..2981cb0366d8b 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -27,9 +27,11 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(76,5): error Type 'T' is not assignable to type 'T & U'. Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error TS2322: Type 'keyof (T & U)' is not assignable to type 'keyof (T | U)'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(84,9): error TS2322: Type 'keyof T' is not assignable to type 'K'. +tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(85,9): error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. -==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (25 errors) ==== +==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (27 errors) ==== class Shape { name: string; width: number; @@ -162,4 +164,18 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error ~~ !!! error TS2322: Type 'keyof (T & U)' is not assignable to type 'keyof (T | U)'. k2 = k1; - } \ No newline at end of file + } + + // Repro from #17166 + function f3(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + ~ +!!! error TS2322: Type 'keyof T' is not assignable to type 'K'. + value = obj[key]; // error, T[keyof T] =/=> T[K] + ~~~~~ +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'. + } + } + + \ No newline at end of file diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.js b/tests/baselines/reference/keyofAndIndexedAccessErrors.js index 838a3a6a86b80..2a1042cf4eeb1 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.js +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.js @@ -77,7 +77,17 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { o2 = o1; // Error k1 = k2; // Error k2 = k1; -} +} + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} + + //// [keyofAndIndexedAccessErrors.js] var Shape = /** @class */ (function () { @@ -109,3 +119,10 @@ function f20(k1, k2, o1, o2) { k1 = k2; // Error k2 = k1; } +// Repro from #17166 +function f3(obj, k, value) { + for (var key in obj) { + k = key; // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols index 36fb8d2989b9c..0e97ef793fb30 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.symbols @@ -268,3 +268,34 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { >k2 : Symbol(k2, Decl(keyofAndIndexedAccessErrors.ts, 69, 37)) >k1 : Symbol(k1, Decl(keyofAndIndexedAccessErrors.ts, 69, 19)) } + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { +>f3 : Symbol(f3, Decl(keyofAndIndexedAccessErrors.ts, 78, 1)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 81, 41)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) +>value : Symbol(value, Decl(keyofAndIndexedAccessErrors.ts, 81, 47)) +>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12)) +>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14)) + + for (let key in obj) { +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34)) + + k = key // error, keyof T =/=> K +>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 81, 41)) +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12)) + + value = obj[key]; // error, T[keyof T] =/=> T[K] +>value : Symbol(value, Decl(keyofAndIndexedAccessErrors.ts, 81, 47)) +>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34)) +>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12)) + } +} + + diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.types b/tests/baselines/reference/keyofAndIndexedAccessErrors.types index 4d2e25641d39d..f5cc7c093d92e 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.types +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.types @@ -299,3 +299,37 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { >k2 : keyof (T & U) >k1 : keyof (T | U) } + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { +>f3 : (obj: T, k: K, value: T[K]) => void +>T : T +>K : K +>T : T +>obj : T +>T : T +>k : K +>K : K +>value : T[K] +>T : T +>K : K + + for (let key in obj) { +>key : keyof T +>obj : T + + k = key // error, keyof T =/=> K +>k = key : keyof T +>k : K +>key : keyof T + + value = obj[key]; // error, T[keyof T] =/=> T[K] +>value = obj[key] : T[keyof T] +>value : T[K] +>obj[key] : T[keyof T] +>obj : T +>key : keyof T + } +} + + diff --git a/tests/baselines/reference/mappedTypeRelationships.errors.txt b/tests/baselines/reference/mappedTypeRelationships.errors.txt index 2e51f73179d45..f5d0e66ff3f6c 100644 --- a/tests/baselines/reference/mappedTypeRelationships.errors.txt +++ b/tests/baselines/reference/mappedTypeRelationships.errors.txt @@ -1,106 +1,38 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(11,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[keyof T]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(16,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[K]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(20,5): error TS2536: Type 'keyof U' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(21,5): error TS2322: Type 'T[keyof U]' is not assignable to type 'U[keyof U]'. - Type 'T[string]' is not assignable to type 'U[keyof U]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[keyof U]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(21,12): error TS2536: Type 'keyof U' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(25,5): error TS2536: Type 'K' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(26,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[K]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(26,12): error TS2536: Type 'K' cannot be used to index type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(30,5): error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. Type 'undefined' is not assignable to type 'T[keyof T]'. - Type 'undefined' is not assignable to type 'T[string]'. - Type 'Partial[keyof T]' is not assignable to type 'T[string]'. - Type 'T[keyof T] | undefined' is not assignable to type 'T[string]'. - Type 'undefined' is not assignable to type 'T[string]'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(35,5): error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. Type 'T[K] | undefined' is not assignable to type 'T[K]'. Type 'undefined' is not assignable to type 'T[K]'. - Type 'undefined' is not assignable to type 'T[string]'. - Type 'Partial[K]' is not assignable to type 'T[string]'. - Type 'T[K] | undefined' is not assignable to type 'T[string]'. - Type 'undefined' is not assignable to type 'T[string]'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(40,5): error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'. Type 'undefined' is not assignable to type 'T[keyof T]'. - Type 'undefined' is not assignable to type 'T[string]'. - Type 'Partial[keyof T]' is not assignable to type 'T[string]'. - Type 'U[keyof T] | undefined' is not assignable to type 'T[string]'. - Type 'undefined' is not assignable to type 'T[string]'. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(41,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'Partial[keyof T]'. - Type 'T[string]' is not assignable to type 'Partial[keyof T]'. - Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. - Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[keyof T]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(45,5): error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. Type 'U[K] | undefined' is not assignable to type 'T[K]'. Type 'undefined' is not assignable to type 'T[K]'. - Type 'undefined' is not assignable to type 'T[string]'. - Type 'Partial[K]' is not assignable to type 'T[string]'. - Type 'U[K] | undefined' is not assignable to type 'T[string]'. - Type 'undefined' is not assignable to type 'T[string]'. -tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(46,5): error TS2322: Type 'T[K]' is not assignable to type 'Partial[K]'. - Type 'T[string]' is not assignable to type 'Partial[K]'. - Type 'T[string]' is not assignable to type 'U[K] | undefined'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[K]' is not assignable to type 'U[K] | undefined'. - Type 'T[string]' is not assignable to type 'U[K] | undefined'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[K]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(51,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(56,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'Readonly[keyof T]'. - Type 'T[string]' is not assignable to type 'Readonly[keyof T]'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[keyof T]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[keyof T]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'Readonly'. + Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2322: Type 'T[K]' is not assignable to type 'Readonly[K]'. - Type 'T[string]' is not assignable to type 'Readonly[K]'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[K]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[K]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[K]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'Readonly'. + Type 'T[K]' is not assignable to type 'U[K]'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(66,5): error TS2542: Index signature in type 'Readonly' only permits reading. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(72,5): error TS2322: Type 'Partial' is not assignable to type 'T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(78,5): error TS2322: Type 'Partial' is not assignable to type 'Partial'. @@ -108,11 +40,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(88,5): error TS2 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(127,5): error TS2322: Type 'Partial' is not assignable to type 'Identity'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(143,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. Type 'T[P]' is not assignable to type 'U[P]'. - Type 'T[string]' is not assignable to type 'U[P]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[P]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(148,5): error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof U]: U[P]; }'. Type 'keyof U' is not assignable to type 'keyof T'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(153,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in keyof T]: T[P]; }'. @@ -123,14 +51,10 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(163,5): error TS Type 'keyof T' is not assignable to type 'K'. tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in K]: U[P]; }'. Type 'T[P]' is not assignable to type 'U[P]'. - Type 'T[string]' is not assignable to type 'U[P]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T[P]' is not assignable to type 'U[string]'. - Type 'T[string]' is not assignable to type 'U[string]'. - Type 'T' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. -==== tests/cases/conformance/types/mapped/mappedTypeRelationships.ts (30 errors) ==== +==== tests/cases/conformance/types/mapped/mappedTypeRelationships.ts (28 errors) ==== function f1(x: T, k: keyof T) { return x[k]; } @@ -144,11 +68,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f4(x: T, y: U, k: K) { @@ -156,11 +76,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f5(x: T, y: U, k: keyof U) { @@ -170,11 +86,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[keyof U]' is not assignable to type 'U[keyof U]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof U]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[keyof U]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2536: Type 'keyof U' cannot be used to index type 'T'. } @@ -186,11 +98,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2536: Type 'K' cannot be used to index type 'T'. } @@ -201,10 +109,6 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS !!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. !!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[keyof T]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'T[keyof T] | undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; } @@ -214,10 +118,6 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS !!! error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. !!! error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[K]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'Partial[K]' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'T[K] | undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; } @@ -227,25 +127,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS !!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[keyof T]'. !!! error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[keyof T]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[keyof T]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'Partial[keyof T]' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'U[keyof T] | undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; // Error - ~~~~ -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'Partial[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'Partial[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f13(x: T, y: Partial, k: K) { @@ -254,25 +136,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS !!! error TS2322: Type 'Partial[K]' is not assignable to type 'T[K]'. !!! error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'. !!! error TS2322: Type 'undefined' is not assignable to type 'T[K]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'Partial[K]' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[string]'. -!!! error TS2322: Type 'undefined' is not assignable to type 'T[string]'. y[k] = x[k]; // Error - ~~~~ -!!! error TS2322: Type 'T[K]' is not assignable to type 'Partial[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'Partial[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K] | undefined'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f20(x: T, y: Readonly, k: keyof T) { @@ -294,14 +158,9 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[keyof T]' is not assignable to type 'Readonly[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'Readonly[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'Readonly'. +!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2542: Index signature in type 'Readonly' only permits reading. } @@ -311,14 +170,9 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS y[k] = x[k]; // Error ~~~~ !!! error TS2322: Type 'T[K]' is not assignable to type 'Readonly[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'Readonly[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[K]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'Readonly'. +!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. ~~~~ !!! error TS2542: Index signature in type 'Readonly' only permits reading. } @@ -409,11 +263,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in keyof T]: T[P]; }' is not assignable to type '{ [P in keyof T]: U[P]; }'. !!! error TS2322: Type 'T[P]' is not assignable to type 'U[P]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[P]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[P]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f72(x: { [P in keyof T]: T[P] }, y: { [P in keyof U]: U[P] }) { @@ -454,11 +304,7 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS ~ !!! error TS2322: Type '{ [P in K]: T[P]; }' is not assignable to type '{ [P in K]: U[P]; }'. !!! error TS2322: Type 'T[P]' is not assignable to type 'U[P]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[P]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[P]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T[string]' is not assignable to type 'U[string]'. -!!! error TS2322: Type 'T' is not assignable to type 'U'. +!!! error TS2322: Type 'T' is not assignable to type 'U'. } function f80(t: T): Partial { diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt new file mode 100644 index 0000000000000..56781157131a4 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.errors.txt @@ -0,0 +1,67 @@ +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(3,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(6,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(9,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(12,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(15,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(18,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(21,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(24,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(27,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. +tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts(30,5): error TS2322: Type 'string' is not assignable to type 'T[P]'. + Type 'string' is not assignable to type 'number'. + + +==== tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts (10 errors) ==== + // test for #15371 + function f(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function g(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function h(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function i(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function j(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function k(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function o(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function l(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function m(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. + } + function n(s: string, tp: T[P]): void { + tp = s; + ~~ +!!! error TS2322: Type 'string' is not assignable to type 'T[P]'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.js b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.js new file mode 100644 index 0000000000000..7a24345a94b11 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.js @@ -0,0 +1,67 @@ +//// [nonPrimitiveConstraintOfIndexAccessType.ts] +// test for #15371 +function f(s: string, tp: T[P]): void { + tp = s; +} +function g(s: string, tp: T[P]): void { + tp = s; +} +function h(s: string, tp: T[P]): void { + tp = s; +} +function i(s: string, tp: T[P]): void { + tp = s; +} +function j(s: string, tp: T[P]): void { + tp = s; +} +function k(s: string, tp: T[P]): void { + tp = s; +} +function o(s: string, tp: T[P]): void { + tp = s; +} +function l(s: string, tp: T[P]): void { + tp = s; +} +function m(s: string, tp: T[P]): void { + tp = s; +} +function n(s: string, tp: T[P]): void { + tp = s; +} + + +//// [nonPrimitiveConstraintOfIndexAccessType.js] +"use strict"; +// test for #15371 +function f(s, tp) { + tp = s; +} +function g(s, tp) { + tp = s; +} +function h(s, tp) { + tp = s; +} +function i(s, tp) { + tp = s; +} +function j(s, tp) { + tp = s; +} +function k(s, tp) { + tp = s; +} +function o(s, tp) { + tp = s; +} +function l(s, tp) { + tp = s; +} +function m(s, tp) { + tp = s; +} +function n(s, tp) { + tp = s; +} diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.symbols b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.symbols new file mode 100644 index 0000000000000..3ada1e3f3d1c8 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.symbols @@ -0,0 +1,145 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts === +// test for #15371 +function f(s: string, tp: T[P]): void { +>f : Symbol(f, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 0, 0)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 28)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 48)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 58)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 28)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 58)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 1, 48)) +} +function g(s: string, tp: T[P]): void { +>g : Symbol(g, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 3, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 26)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 46)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 56)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 26)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 56)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 4, 46)) +} +function h(s: string, tp: T[P]): void { +>h : Symbol(h, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 6, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 31)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 51)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 61)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 31)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 61)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 7, 51)) +} +function i(s: string, tp: T[P]): void { +>i : Symbol(i, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 9, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 26)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 46)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 56)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 26)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 56)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 10, 46)) +} +function j(s: string, tp: T[P]): void { +>j : Symbol(j, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 12, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 27)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 47)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 57)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 27)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 57)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 13, 47)) +} +function k(s: string, tp: T[P]): void { +>k : Symbol(k, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 15, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 28)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 48)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 58)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 28)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 58)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 16, 48)) +} +function o(s: string, tp: T[P]): void { +>o : Symbol(o, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 18, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 28)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 48)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 58)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 28)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 58)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 19, 48)) +} +function l(s: string, tp: T[P]): void { +>l : Symbol(l, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 21, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 24)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 44)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 54)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 24)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 54)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 22, 44)) +} +function m(s: string, tp: T[P]): void { +>m : Symbol(m, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 24, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 11)) +>a : Symbol(a, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 22)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 35)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 55)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 65)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 35)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 65)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 25, 55)) +} +function n(s: string, tp: T[P]): void { +>n : Symbol(n, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 27, 1)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 24)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 45)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 11)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 65)) +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 75)) +>T : Symbol(T, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 11)) +>P : Symbol(P, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 45)) + + tp = s; +>tp : Symbol(tp, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 75)) +>s : Symbol(s, Decl(nonPrimitiveConstraintOfIndexAccessType.ts, 28, 65)) +} + diff --git a/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.types b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.types new file mode 100644 index 0000000000000..d5e8560d7cf46 --- /dev/null +++ b/tests/baselines/reference/nonPrimitiveConstraintOfIndexAccessType.types @@ -0,0 +1,156 @@ +=== tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts === +// test for #15371 +function f(s: string, tp: T[P]): void { +>f : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function g(s: string, tp: T[P]): void { +>g : (s: string, tp: T[P]) => void +>T : T +>null : null +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function h(s: string, tp: T[P]): void { +>h : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function i(s: string, tp: T[P]): void { +>i : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function j(s: string, tp: T[P]): void { +>j : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function k(s: string, tp: T[P]): void { +>k : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function o(s: string, tp: T[P]): void { +>o : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function l(s: string, tp: T[P]): void { +>l : (s: string, tp: T[P]) => void +>T : T +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function m(s: string, tp: T[P]): void { +>m : (s: string, tp: T[P]) => void +>T : T +>a : number +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} +function n(s: string, tp: T[P]): void { +>n : (s: string, tp: T[P]) => void +>T : T +>s : string +>P : P +>T : T +>s : string +>tp : T[P] +>T : T +>P : P + + tp = s; +>tp = s : string +>tp : T[P] +>s : string +} + diff --git a/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts b/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts new file mode 100644 index 0000000000000..2303bb33944ad --- /dev/null +++ b/tests/cases/conformance/expressions/binaryOperators/additionOperator/additionOperatorWithConstrainedTypeParameter.ts @@ -0,0 +1,11 @@ +// test for #17069 +function sum, K extends string>(n: number, v: T, k: K) { + n = n + v[k]; + n += v[k]; // += should work the same way +} +function realSum, K extends string>(n: number, vs: T[], k: K) { + for (const v of vs) { + n = n + v[k]; + n += v[k]; + } +} diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts index cbbc9a5220086..ffc5076831ae0 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts @@ -76,4 +76,13 @@ function f20(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) { o2 = o1; // Error k1 = k2; // Error k2 = k1; -} \ No newline at end of file +} + +// Repro from #17166 +function f3(obj: T, k: K, value: T[K]): void { + for (let key in obj) { + k = key // error, keyof T =/=> K + value = obj[key]; // error, T[keyof T] =/=> T[K] + } +} + diff --git a/tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts new file mode 100644 index 0000000000000..1e852f12f928e --- /dev/null +++ b/tests/cases/conformance/types/nonPrimitive/nonPrimitiveConstraintOfIndexAccessType.ts @@ -0,0 +1,32 @@ +// @strict: true +// test for #15371 +function f(s: string, tp: T[P]): void { + tp = s; +} +function g(s: string, tp: T[P]): void { + tp = s; +} +function h(s: string, tp: T[P]): void { + tp = s; +} +function i(s: string, tp: T[P]): void { + tp = s; +} +function j(s: string, tp: T[P]): void { + tp = s; +} +function k(s: string, tp: T[P]): void { + tp = s; +} +function o(s: string, tp: T[P]): void { + tp = s; +} +function l(s: string, tp: T[P]): void { + tp = s; +} +function m(s: string, tp: T[P]): void { + tp = s; +} +function n(s: string, tp: T[P]): void { + tp = s; +}