diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 418be79878e35..eeb29c1fcb378 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7651,7 +7651,7 @@ namespace ts { // If a type parameter does not have a default type, or if the default type // is a forward reference, the empty object type is used. for (let i = numTypeArguments; i < numTypeParameters; i++) { - result[i] = getDefaultTypeArgumentType(isJavaScriptImplicitAny); + result[i] = getConstraintFromTypeParameter(typeParameters![i]) || getDefaultTypeArgumentType(isJavaScriptImplicitAny); } for (let i = numTypeArguments; i < numTypeParameters; i++) { const mapper = createTypeMapper(typeParameters!, result); diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.errors.txt b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.errors.txt new file mode 100644 index 0000000000000..71e3ef046277a --- /dev/null +++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts(3,18): error TS2322: Type '{ foo: string; }' is not assignable to type 'Test'. + Object literal may only specify known properties, and 'foo' does not exist in type 'Test'. +tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts(5,19): error TS2322: Type '{}' is not assignable to type 'string'. + + +==== tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts (2 errors) ==== + type Test = { value: T }; + + let zz: Test = { foo: "abc" }; // should error on comparison with Test + ~~~~~~~~~~ +!!! error TS2322: Type '{ foo: string; }' is not assignable to type 'Test'. +!!! error TS2322: Object literal may only specify known properties, and 'foo' does not exist in type 'Test'. + + let zzy: Test = { value: {} }; // should error + ~~~~~ +!!! error TS2322: Type '{}' is not assignable to type 'string'. +!!! related TS6500 tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts:1:37: The expected type comes from property 'value' which is declared here on type 'Test' + \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.js b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.js new file mode 100644 index 0000000000000..296a0063fe270 --- /dev/null +++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.js @@ -0,0 +1,11 @@ +//// [typeArgumentDefaultUsesConstraintOnCircularDefault.ts] +type Test = { value: T }; + +let zz: Test = { foo: "abc" }; // should error on comparison with Test + +let zzy: Test = { value: {} }; // should error + + +//// [typeArgumentDefaultUsesConstraintOnCircularDefault.js] +var zz = { foo: "abc" }; // should error on comparison with Test +var zzy = { value: {} }; // should error diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.symbols b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.symbols new file mode 100644 index 0000000000000..2181e34188964 --- /dev/null +++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.symbols @@ -0,0 +1,18 @@ +=== tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts === +type Test = { value: T }; +>Test : Symbol(Test, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 0)) +>T : Symbol(T, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 10)) +>T : Symbol(T, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 10)) +>value : Symbol(value, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 35)) +>T : Symbol(T, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 10)) + +let zz: Test = { foo: "abc" }; // should error on comparison with Test +>zz : Symbol(zz, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 2, 3)) +>Test : Symbol(Test, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 0)) +>foo : Symbol(foo, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 2, 16)) + +let zzy: Test = { value: {} }; // should error +>zzy : Symbol(zzy, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 4, 3)) +>Test : Symbol(Test, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 0, 0)) +>value : Symbol(value, Decl(typeArgumentDefaultUsesConstraintOnCircularDefault.ts, 4, 17)) + diff --git a/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.types b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.types new file mode 100644 index 0000000000000..7c0d469da4619 --- /dev/null +++ b/tests/baselines/reference/typeArgumentDefaultUsesConstraintOnCircularDefault.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts === +type Test = { value: T }; +>Test : Test +>value : T + +let zz: Test = { foo: "abc" }; // should error on comparison with Test +>zz : Test +>{ foo: "abc" } : { foo: string; } +>foo : string +>"abc" : "abc" + +let zzy: Test = { value: {} }; // should error +>zzy : Test +>{ value: {} } : { value: {}; } +>value : {} +>{} : {} + diff --git a/tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts b/tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts new file mode 100644 index 0000000000000..b8361ea571496 --- /dev/null +++ b/tests/cases/compiler/typeArgumentDefaultUsesConstraintOnCircularDefault.ts @@ -0,0 +1,5 @@ +type Test = { value: T }; + +let zz: Test = { foo: "abc" }; // should error on comparison with Test + +let zzy: Test = { value: {} }; // should error