diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8a5d99e8f69af..d27a08385e016 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2053,7 +2053,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var noConstraintType = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, emptyArray); var circularConstraintType = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, emptyArray); var resolvingDefaultType = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, emptyArray); - var resolvingApparentMappedType = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, emptyArray); var markerSuperType = createTypeParameter(); var markerSubType = createTypeParameter(); @@ -14539,32 +14538,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function getApparentTypeOfMappedType(type: MappedType) { - if (type.resolvedApparentType) { - if (type.resolvedApparentType === resolvingApparentMappedType) { - return type.resolvedApparentType = type; - } - return type.resolvedApparentType; - } - type.resolvedApparentType = resolvingApparentMappedType; - return type.resolvedApparentType = getResolvedApparentTypeOfMappedType(type); + return type.resolvedApparentType || (type.resolvedApparentType = getResolvedApparentTypeOfMappedType(type)); } function getResolvedApparentTypeOfMappedType(type: MappedType) { - const mappedType = type.target as MappedType || type; - const typeVariable = getHomomorphicTypeVariable(mappedType); - if (typeVariable && !mappedType.declaration.nameType) { - let constraint: Type | undefined; - if (!type.target) { - constraint = getConstraintOfTypeParameter(typeVariable); - } - else { - const modifiersConstraint = getConstraintOfType(getModifiersTypeFromMappedType(type)); - if (modifiersConstraint) { - constraint = getApparentType(modifiersConstraint); - } - } + const typeVariable = getHomomorphicTypeVariable(type); + if (typeVariable && !type.declaration.nameType) { + const constraint = getConstraintOfTypeParameter(typeVariable); if (constraint && everyType(constraint, isArrayOrTupleType)) { - return instantiateType(mappedType, prependTypeMapping(typeVariable, constraint, mappedType.mapper)); + return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper)); } } return type; diff --git a/tests/baselines/reference/homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.symbols b/tests/baselines/reference/homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.symbols deleted file mode 100644 index 1d4d93ed814b4..0000000000000 --- a/tests/baselines/reference/homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.symbols +++ /dev/null @@ -1,92 +0,0 @@ -//// [tests/cases/compiler/homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts] //// - -=== homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts === -type HandleOptions = { ->HandleOptions : Symbol(HandleOptions, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 0, 0)) ->O : Symbol(O, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 0, 19)) - - [I in keyof O]: { ->I : Symbol(I, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 1, 3)) ->O : Symbol(O, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 0, 19)) - - value: O[I]; ->value : Symbol(value, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 1, 19)) ->O : Symbol(O, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 0, 19)) ->I : Symbol(I, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 1, 3)) - - }; -}; - -declare function func1< ->func1 : Symbol(func1, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 4, 2)) - - T extends Record, ->T : Symbol(T, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 6, 23)) ->Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->PropertyKey : Symbol(PropertyKey, Decl(lib.es5.d.ts, --, --)) - ->(fields: { ->fields : Symbol(fields, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 8, 2)) - - [K in keyof T]: { ->K : Symbol(K, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 9, 3)) ->T : Symbol(T, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 6, 23)) - - label: string; ->label : Symbol(label, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 9, 19)) - - options: [...HandleOptions]; ->options : Symbol(options, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 10, 18)) ->HandleOptions : Symbol(HandleOptions, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 0, 0)) ->T : Symbol(T, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 6, 23)) ->K : Symbol(K, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 9, 3)) - - }; -}): T; ->T : Symbol(T, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 6, 23)) - -const result = func1({ ->result : Symbol(result, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 15, 5)) ->func1 : Symbol(func1, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 4, 2)) - - prop: { ->prop : Symbol(prop, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 15, 22)) - - label: "first", ->label : Symbol(label, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 16, 9)) - - options: [ ->options : Symbol(options, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 17, 19)) - { - value: 123, ->value : Symbol(value, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 19, 7)) - - }, - { - value: "foo", ->value : Symbol(value, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 22, 7)) - - }, - ], - }, - other: { ->other : Symbol(other, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 26, 4)) - - label: "second", ->label : Symbol(label, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 27, 10)) - - options: [ ->options : Symbol(options, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 28, 20)) - { - value: "bar", ->value : Symbol(value, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 30, 7)) - - }, - { - value: true, ->value : Symbol(value, Decl(homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts, 33, 7)) - - }, - ], - }, -}); diff --git a/tests/baselines/reference/homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.types b/tests/baselines/reference/homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.types deleted file mode 100644 index 19d882824d22f..0000000000000 --- a/tests/baselines/reference/homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.types +++ /dev/null @@ -1,95 +0,0 @@ -//// [tests/cases/compiler/homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts] //// - -=== homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts === -type HandleOptions = { ->HandleOptions : HandleOptions - - [I in keyof O]: { - value: O[I]; ->value : O[I] - - }; -}; - -declare function func1< ->func1 : >(fields: { [K in keyof T]: { label: string; options: [...HandleOptions]; }; }) => T - - T extends Record, ->(fields: { ->fields : { [K in keyof T]: { label: string; options: [...HandleOptions]; }; } - - [K in keyof T]: { - label: string; ->label : string - - options: [...HandleOptions]; ->options : [...HandleOptions] - - }; -}): T; - -const result = func1({ ->result : { prop: [number, string]; other: [string, boolean]; } ->func1({ prop: { label: "first", options: [ { value: 123, }, { value: "foo", }, ], }, other: { label: "second", options: [ { value: "bar", }, { value: true, }, ], },}) : { prop: [number, string]; other: [string, boolean]; } ->func1 : >(fields: { [K in keyof T]: { label: string; options: [...HandleOptions]; }; }) => T ->{ prop: { label: "first", options: [ { value: 123, }, { value: "foo", }, ], }, other: { label: "second", options: [ { value: "bar", }, { value: true, }, ], },} : { prop: { label: string; options: [{ value: number; }, { value: string; }]; }; other: { label: string; options: [{ value: string; }, { value: true; }]; }; } - - prop: { ->prop : { label: string; options: [{ value: number; }, { value: string; }]; } ->{ label: "first", options: [ { value: 123, }, { value: "foo", }, ], } : { label: string; options: [{ value: number; }, { value: string; }]; } - - label: "first", ->label : string ->"first" : "first" - - options: [ ->options : [{ value: number; }, { value: string; }] ->[ { value: 123, }, { value: "foo", }, ] : [{ value: number; }, { value: string; }] - { ->{ value: 123, } : { value: number; } - - value: 123, ->value : number ->123 : 123 - - }, - { ->{ value: "foo", } : { value: string; } - - value: "foo", ->value : string ->"foo" : "foo" - - }, - ], - }, - other: { ->other : { label: string; options: [{ value: string; }, { value: true; }]; } ->{ label: "second", options: [ { value: "bar", }, { value: true, }, ], } : { label: string; options: [{ value: string; }, { value: true; }]; } - - label: "second", ->label : string ->"second" : "second" - - options: [ ->options : [{ value: string; }, { value: true; }] ->[ { value: "bar", }, { value: true, }, ] : [{ value: string; }, { value: true; }] - { ->{ value: "bar", } : { value: string; } - - value: "bar", ->value : string ->"bar" : "bar" - - }, - { ->{ value: true, } : { value: true; } - - value: true, ->value : true ->true : true - - }, - ], - }, -}); diff --git a/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.symbols b/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.symbols new file mode 100644 index 0000000000000..3d6cd20bb2516 --- /dev/null +++ b/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.symbols @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/nestedHomomorphicMappedTypesWithArrayConstraint1.ts] //// + +=== nestedHomomorphicMappedTypesWithArrayConstraint1.ts === +// Based on @types/sinon v10 + +type MatchArguments = { +>MatchArguments : Symbol(MatchArguments, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 0, 0)) +>T : Symbol(T, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 2, 20)) + + [K in keyof T]: T[K]; +>K : Symbol(K, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 3, 5)) +>T : Symbol(T, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 2, 20)) +>T : Symbol(T, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 2, 20)) +>K : Symbol(K, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 3, 5)) + +}; + +interface SinonSpyCallApi { +>SinonSpyCallApi : Symbol(SinonSpyCallApi, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 4, 2)) +>TArgs : Symbol(TArgs, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 6, 26)) + + calledWith(...args: Partial>): boolean; +>calledWith : Symbol(SinonSpyCallApi.calledWith, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 6, 56)) +>args : Symbol(args, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 7, 15)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>MatchArguments : Symbol(MatchArguments, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 0, 0)) +>TArgs : Symbol(TArgs, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 6, 26)) +} diff --git a/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.types b/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.types new file mode 100644 index 0000000000000..a6415f811583e --- /dev/null +++ b/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.types @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/nestedHomomorphicMappedTypesWithArrayConstraint1.ts] //// + +=== nestedHomomorphicMappedTypesWithArrayConstraint1.ts === +// Based on @types/sinon v10 + +type MatchArguments = { +>MatchArguments : MatchArguments + + [K in keyof T]: T[K]; +}; + +interface SinonSpyCallApi { + calledWith(...args: Partial>): boolean; +>calledWith : (...args: Partial>) => boolean +>args : Partial> +} diff --git a/tests/cases/compiler/homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts b/tests/cases/compiler/homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts deleted file mode 100644 index e3e880dd4ae14..0000000000000 --- a/tests/cases/compiler/homomorphicMappedTypeWithNonHomomorphicInstantiationSpreadable1.ts +++ /dev/null @@ -1,42 +0,0 @@ -// @strict: true -// @noEmit: true - -type HandleOptions = { - [I in keyof O]: { - value: O[I]; - }; -}; - -declare function func1< - T extends Record, ->(fields: { - [K in keyof T]: { - label: string; - options: [...HandleOptions]; - }; -}): T; - -const result = func1({ - prop: { - label: "first", - options: [ - { - value: 123, - }, - { - value: "foo", - }, - ], - }, - other: { - label: "second", - options: [ - { - value: "bar", - }, - { - value: true, - }, - ], - }, -}); \ No newline at end of file diff --git a/tests/cases/compiler/nestedHomomorphicMappedTypesWithArrayConstraint1.ts b/tests/cases/compiler/nestedHomomorphicMappedTypesWithArrayConstraint1.ts new file mode 100644 index 0000000000000..bbf442cbecdd3 --- /dev/null +++ b/tests/cases/compiler/nestedHomomorphicMappedTypesWithArrayConstraint1.ts @@ -0,0 +1,12 @@ +// @strict: true +// @noEmit: true + +// Based on @types/sinon v10 + +type MatchArguments = { + [K in keyof T]: T[K]; +}; + +interface SinonSpyCallApi { + calledWith(...args: Partial>): boolean; +} \ No newline at end of file