diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8a5d99e8f69af..72fa15062891b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14558,9 +14558,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { constraint = getConstraintOfTypeParameter(typeVariable); } else { - const modifiersConstraint = getConstraintOfType(getModifiersTypeFromMappedType(type)); - if (modifiersConstraint) { - constraint = getApparentType(modifiersConstraint); + const modifiersType = getModifiersTypeFromMappedType(type); + if (modifiersType) { + constraint = getApparentType(getConstraintOfType(modifiersType) || modifiersType); } } if (constraint && everyType(constraint, isArrayOrTupleType)) { diff --git a/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.symbols b/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.symbols new file mode 100644 index 0000000000000..ec1154b4e308e --- /dev/null +++ b/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.symbols @@ -0,0 +1,48 @@ +//// [tests/cases/compiler/nestedHomomorphicMappedTypesWithArrayConstraint1.ts] //// + +=== nestedHomomorphicMappedTypesWithArrayConstraint1.ts === +interface SinonMatcher { +>SinonMatcher : Symbol(SinonMatcher, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 0, 0)) + + and(expr: SinonMatcher): SinonMatcher; +>and : Symbol(SinonMatcher.and, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 0, 24)) +>expr : Symbol(expr, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 1, 6)) +>SinonMatcher : Symbol(SinonMatcher, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 0, 0)) +>SinonMatcher : Symbol(SinonMatcher, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 0, 0)) + + or(expr: SinonMatcher): SinonMatcher; +>or : Symbol(SinonMatcher.or, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 1, 40)) +>expr : Symbol(expr, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 2, 5)) +>SinonMatcher : Symbol(SinonMatcher, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 0, 0)) +>SinonMatcher : Symbol(SinonMatcher, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 0, 0)) + + test(val: any): boolean; +>test : Symbol(SinonMatcher.test, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 2, 39)) +>val : Symbol(val, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 3, 7)) +} + +type MatchArguments = { +>MatchArguments : Symbol(MatchArguments, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 4, 1)) +>T : Symbol(T, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 6, 20)) + + [K in keyof T]: SinonMatcher | T[K]; +>K : Symbol(K, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 7, 3)) +>T : Symbol(T, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 6, 20)) +>SinonMatcher : Symbol(SinonMatcher, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 0, 0)) +>T : Symbol(T, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 6, 20)) +>K : Symbol(K, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 7, 3)) + +}; + +interface SinonSpyCallApi { +>SinonSpyCallApi : Symbol(SinonSpyCallApi, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 8, 2)) +>TArgs : Symbol(TArgs, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 10, 26)) + + calledWith(...args: Partial>): boolean; +>calledWith : Symbol(SinonSpyCallApi.calledWith, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 10, 56)) +>args : Symbol(args, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 11, 13)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>MatchArguments : Symbol(MatchArguments, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 4, 1)) +>TArgs : Symbol(TArgs, Decl(nestedHomomorphicMappedTypesWithArrayConstraint1.ts, 10, 26)) +} + diff --git a/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.types b/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.types new file mode 100644 index 0000000000000..aff42b5041aa1 --- /dev/null +++ b/tests/baselines/reference/nestedHomomorphicMappedTypesWithArrayConstraint1.types @@ -0,0 +1,29 @@ +//// [tests/cases/compiler/nestedHomomorphicMappedTypesWithArrayConstraint1.ts] //// + +=== nestedHomomorphicMappedTypesWithArrayConstraint1.ts === +interface SinonMatcher { + and(expr: SinonMatcher): SinonMatcher; +>and : (expr: SinonMatcher) => SinonMatcher +>expr : SinonMatcher + + or(expr: SinonMatcher): SinonMatcher; +>or : (expr: SinonMatcher) => SinonMatcher +>expr : SinonMatcher + + test(val: any): boolean; +>test : (val: any) => boolean +>val : any +} + +type MatchArguments = { +>MatchArguments : MatchArguments + + [K in keyof T]: SinonMatcher | T[K]; +}; + +interface SinonSpyCallApi { + calledWith(...args: Partial>): boolean; +>calledWith : (...args: Partial>) => boolean +>args : Partial> +} + diff --git a/tests/cases/compiler/nestedHomomorphicMappedTypesWithArrayConstraint1.ts b/tests/cases/compiler/nestedHomomorphicMappedTypesWithArrayConstraint1.ts new file mode 100644 index 0000000000000..66a527c50e817 --- /dev/null +++ b/tests/cases/compiler/nestedHomomorphicMappedTypesWithArrayConstraint1.ts @@ -0,0 +1,16 @@ +// @strict: true +// @noEmit: true + +interface SinonMatcher { + and(expr: SinonMatcher): SinonMatcher; + or(expr: SinonMatcher): SinonMatcher; + test(val: any): boolean; +} + +type MatchArguments = { + [K in keyof T]: SinonMatcher | T[K]; +}; + +interface SinonSpyCallApi { + calledWith(...args: Partial>): boolean; +}