diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c434721d7145b..f182ce899ce46 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5906,9 +5906,14 @@ namespace ts { if (source.flags & TypeFlags.TypeParameter) { let constraint = getConstraintOfTypeParameter(source); + if (!constraint || constraint.flags & TypeFlags.Any) { constraint = emptyObjectType; } + + // The constraint may need to be further instantiated with its 'this' type. + constraint = getTypeWithThisArgument(constraint, source); + // Report constraint errors only if the constraint is not the empty object type const reportConstraintErrors = reportErrors && constraint !== emptyObjectType; if (result = isRelatedTo(constraint, target, reportConstraintErrors)) { diff --git a/tests/baselines/reference/fuzzy.errors.txt b/tests/baselines/reference/fuzzy.errors.txt index 344a3865fb2a5..19f0ad56a5e35 100644 --- a/tests/baselines/reference/fuzzy.errors.txt +++ b/tests/baselines/reference/fuzzy.errors.txt @@ -4,7 +4,6 @@ tests/cases/compiler/fuzzy.ts(21,20): error TS2322: Type '{ anything: number; on Types of property 'oneI' are incompatible. Type 'this' is not assignable to type 'I'. Type 'C' is not assignable to type 'I'. - Property 'alsoWorks' is missing in type 'C'. tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Type '{ oneI: this; }' cannot be converted to type 'R'. Property 'anything' is missing in type '{ oneI: this; }'. @@ -39,7 +38,6 @@ tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Type '{ oneI: this; }' canno !!! error TS2322: Types of property 'oneI' are incompatible. !!! error TS2322: Type 'this' is not assignable to type 'I'. !!! error TS2322: Type 'C' is not assignable to type 'I'. -!!! error TS2322: Property 'alsoWorks' is missing in type 'C'. } worksToo():R { diff --git a/tests/baselines/reference/recurringTypeParamForContainerOfBase01.js b/tests/baselines/reference/recurringTypeParamForContainerOfBase01.js new file mode 100644 index 0000000000000..b3ef0cba312f2 --- /dev/null +++ b/tests/baselines/reference/recurringTypeParamForContainerOfBase01.js @@ -0,0 +1,27 @@ +//// [recurringTypeParamForContainerOfBase01.ts] + +interface BoxOfFoo> { + item: T +} + +interface Foo> { + self: T; +} + +interface Bar> extends Foo { + other: BoxOfFoo; +} + +//// [recurringTypeParamForContainerOfBase01.js] + + +//// [recurringTypeParamForContainerOfBase01.d.ts] +interface BoxOfFoo> { + item: T; +} +interface Foo> { + self: T; +} +interface Bar> extends Foo { + other: BoxOfFoo; +} diff --git a/tests/baselines/reference/recurringTypeParamForContainerOfBase01.symbols b/tests/baselines/reference/recurringTypeParamForContainerOfBase01.symbols new file mode 100644 index 0000000000000..48ea1ffa0cf5c --- /dev/null +++ b/tests/baselines/reference/recurringTypeParamForContainerOfBase01.symbols @@ -0,0 +1,37 @@ +=== tests/cases/conformance/types/typeParameters/recurringTypeParamForContainerOfBase01.ts === + +interface BoxOfFoo> { +>BoxOfFoo : Symbol(BoxOfFoo, Decl(recurringTypeParamForContainerOfBase01.ts, 0, 0)) +>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 1, 19)) +>Foo : Symbol(Foo, Decl(recurringTypeParamForContainerOfBase01.ts, 3, 1)) +>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 1, 19)) + + item: T +>item : Symbol(BoxOfFoo.item, Decl(recurringTypeParamForContainerOfBase01.ts, 1, 38)) +>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 1, 19)) +} + +interface Foo> { +>Foo : Symbol(Foo, Decl(recurringTypeParamForContainerOfBase01.ts, 3, 1)) +>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 5, 14)) +>Foo : Symbol(Foo, Decl(recurringTypeParamForContainerOfBase01.ts, 3, 1)) +>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 5, 14)) + + self: T; +>self : Symbol(Foo.self, Decl(recurringTypeParamForContainerOfBase01.ts, 5, 33)) +>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 5, 14)) +} + +interface Bar> extends Foo { +>Bar : Symbol(Bar, Decl(recurringTypeParamForContainerOfBase01.ts, 7, 1)) +>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 9, 14)) +>Bar : Symbol(Bar, Decl(recurringTypeParamForContainerOfBase01.ts, 7, 1)) +>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 9, 14)) +>Foo : Symbol(Foo, Decl(recurringTypeParamForContainerOfBase01.ts, 3, 1)) +>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 9, 14)) + + other: BoxOfFoo; +>other : Symbol(Bar.other, Decl(recurringTypeParamForContainerOfBase01.ts, 9, 48)) +>BoxOfFoo : Symbol(BoxOfFoo, Decl(recurringTypeParamForContainerOfBase01.ts, 0, 0)) +>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 9, 14)) +} diff --git a/tests/baselines/reference/recurringTypeParamForContainerOfBase01.types b/tests/baselines/reference/recurringTypeParamForContainerOfBase01.types new file mode 100644 index 0000000000000..38b23263f01d4 --- /dev/null +++ b/tests/baselines/reference/recurringTypeParamForContainerOfBase01.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/types/typeParameters/recurringTypeParamForContainerOfBase01.ts === + +interface BoxOfFoo> { +>BoxOfFoo : BoxOfFoo +>T : T +>Foo : Foo +>T : T + + item: T +>item : T +>T : T +} + +interface Foo> { +>Foo : Foo +>T : T +>Foo : Foo +>T : T + + self: T; +>self : T +>T : T +} + +interface Bar> extends Foo { +>Bar : Bar +>T : T +>Bar : Bar +>T : T +>Foo : Foo +>T : T + + other: BoxOfFoo; +>other : BoxOfFoo +>BoxOfFoo : BoxOfFoo +>T : T +} diff --git a/tests/baselines/reference/thisTypeInBasePropertyAndDerivedContainerOfBase01.js b/tests/baselines/reference/thisTypeInBasePropertyAndDerivedContainerOfBase01.js new file mode 100644 index 0000000000000..51cc5a24bb649 --- /dev/null +++ b/tests/baselines/reference/thisTypeInBasePropertyAndDerivedContainerOfBase01.js @@ -0,0 +1,27 @@ +//// [thisTypeInBasePropertyAndDerivedContainerOfBase01.ts] + +interface BoxOfFoo { + item: T +} + +interface Foo { + self: this; +} + +interface Bar extends Foo { + other: BoxOfFoo; +} + +//// [thisTypeInBasePropertyAndDerivedContainerOfBase01.js] + + +//// [thisTypeInBasePropertyAndDerivedContainerOfBase01.d.ts] +interface BoxOfFoo { + item: T; +} +interface Foo { + self: this; +} +interface Bar extends Foo { + other: BoxOfFoo; +} diff --git a/tests/baselines/reference/thisTypeInBasePropertyAndDerivedContainerOfBase01.symbols b/tests/baselines/reference/thisTypeInBasePropertyAndDerivedContainerOfBase01.symbols new file mode 100644 index 0000000000000..566bf3aa0935e --- /dev/null +++ b/tests/baselines/reference/thisTypeInBasePropertyAndDerivedContainerOfBase01.symbols @@ -0,0 +1,27 @@ +=== tests/cases/conformance/types/thisType/thisTypeInBasePropertyAndDerivedContainerOfBase01.ts === + +interface BoxOfFoo { +>BoxOfFoo : Symbol(BoxOfFoo, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 0, 0)) +>T : Symbol(T, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 1, 19)) +>Foo : Symbol(Foo, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 3, 1)) + + item: T +>item : Symbol(BoxOfFoo.item, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 1, 35)) +>T : Symbol(T, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 1, 19)) +} + +interface Foo { +>Foo : Symbol(Foo, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 3, 1)) + + self: this; +>self : Symbol(Foo.self, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 5, 15)) +} + +interface Bar extends Foo { +>Bar : Symbol(Bar, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 7, 1)) +>Foo : Symbol(Foo, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 3, 1)) + + other: BoxOfFoo; +>other : Symbol(Bar.other, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 9, 27)) +>BoxOfFoo : Symbol(BoxOfFoo, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 0, 0)) +} diff --git a/tests/baselines/reference/thisTypeInBasePropertyAndDerivedContainerOfBase01.types b/tests/baselines/reference/thisTypeInBasePropertyAndDerivedContainerOfBase01.types new file mode 100644 index 0000000000000..9f6b83df05748 --- /dev/null +++ b/tests/baselines/reference/thisTypeInBasePropertyAndDerivedContainerOfBase01.types @@ -0,0 +1,27 @@ +=== tests/cases/conformance/types/thisType/thisTypeInBasePropertyAndDerivedContainerOfBase01.ts === + +interface BoxOfFoo { +>BoxOfFoo : BoxOfFoo +>T : T +>Foo : Foo + + item: T +>item : T +>T : T +} + +interface Foo { +>Foo : Foo + + self: this; +>self : this +} + +interface Bar extends Foo { +>Bar : Bar +>Foo : Foo + + other: BoxOfFoo; +>other : BoxOfFoo +>BoxOfFoo : BoxOfFoo +} diff --git a/tests/cases/conformance/types/thisType/thisTypeInBasePropertyAndDerivedContainerOfBase01.ts b/tests/cases/conformance/types/thisType/thisTypeInBasePropertyAndDerivedContainerOfBase01.ts new file mode 100644 index 0000000000000..6597f32adc901 --- /dev/null +++ b/tests/cases/conformance/types/thisType/thisTypeInBasePropertyAndDerivedContainerOfBase01.ts @@ -0,0 +1,13 @@ +// @declaration: true + +interface BoxOfFoo { + item: T +} + +interface Foo { + self: this; +} + +interface Bar extends Foo { + other: BoxOfFoo; +} \ No newline at end of file diff --git a/tests/cases/conformance/types/typeParameters/recurringTypeParamForContainerOfBase01.ts b/tests/cases/conformance/types/typeParameters/recurringTypeParamForContainerOfBase01.ts new file mode 100644 index 0000000000000..e8484d30f9512 --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/recurringTypeParamForContainerOfBase01.ts @@ -0,0 +1,13 @@ +// @declaration: true + +interface BoxOfFoo> { + item: T +} + +interface Foo> { + self: T; +} + +interface Bar> extends Foo { + other: BoxOfFoo; +} \ No newline at end of file