Skip to content

Commit 10d09a7

Browse files
Merge pull request #7290 from Microsoft/thisTypesInBasePropAndContainer
Feed the 'this' type as a type argument to constraints during relation checking
2 parents 7ac04dc + b75605e commit 10d09a7

10 files changed

+213
-2
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5906,9 +5906,14 @@ namespace ts {
59065906

59075907
if (source.flags & TypeFlags.TypeParameter) {
59085908
let constraint = getConstraintOfTypeParameter(<TypeParameter>source);
5909+
59095910
if (!constraint || constraint.flags & TypeFlags.Any) {
59105911
constraint = emptyObjectType;
59115912
}
5913+
5914+
// The constraint may need to be further instantiated with its 'this' type.
5915+
constraint = getTypeWithThisArgument(constraint, source);
5916+
59125917
// Report constraint errors only if the constraint is not the empty object type
59135918
const reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
59145919
if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {

tests/baselines/reference/fuzzy.errors.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ tests/cases/compiler/fuzzy.ts(21,20): error TS2322: Type '{ anything: number; on
44
Types of property 'oneI' are incompatible.
55
Type 'this' is not assignable to type 'I'.
66
Type 'C' is not assignable to type 'I'.
7-
Property 'alsoWorks' is missing in type 'C'.
87
tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Type '{ oneI: this; }' cannot be converted to type 'R'.
98
Property 'anything' is missing in type '{ oneI: this; }'.
109

@@ -39,7 +38,6 @@ tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Type '{ oneI: this; }' canno
3938
!!! error TS2322: Types of property 'oneI' are incompatible.
4039
!!! error TS2322: Type 'this' is not assignable to type 'I'.
4140
!!! error TS2322: Type 'C' is not assignable to type 'I'.
42-
!!! error TS2322: Property 'alsoWorks' is missing in type 'C'.
4341
}
4442

4543
worksToo():R {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//// [recurringTypeParamForContainerOfBase01.ts]
2+
3+
interface BoxOfFoo<T extends Foo<T>> {
4+
item: T
5+
}
6+
7+
interface Foo<T extends Foo<T>> {
8+
self: T;
9+
}
10+
11+
interface Bar<T extends Bar<T>> extends Foo<T> {
12+
other: BoxOfFoo<T>;
13+
}
14+
15+
//// [recurringTypeParamForContainerOfBase01.js]
16+
17+
18+
//// [recurringTypeParamForContainerOfBase01.d.ts]
19+
interface BoxOfFoo<T extends Foo<T>> {
20+
item: T;
21+
}
22+
interface Foo<T extends Foo<T>> {
23+
self: T;
24+
}
25+
interface Bar<T extends Bar<T>> extends Foo<T> {
26+
other: BoxOfFoo<T>;
27+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
=== tests/cases/conformance/types/typeParameters/recurringTypeParamForContainerOfBase01.ts ===
2+
3+
interface BoxOfFoo<T extends Foo<T>> {
4+
>BoxOfFoo : Symbol(BoxOfFoo, Decl(recurringTypeParamForContainerOfBase01.ts, 0, 0))
5+
>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 1, 19))
6+
>Foo : Symbol(Foo, Decl(recurringTypeParamForContainerOfBase01.ts, 3, 1))
7+
>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 1, 19))
8+
9+
item: T
10+
>item : Symbol(BoxOfFoo.item, Decl(recurringTypeParamForContainerOfBase01.ts, 1, 38))
11+
>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 1, 19))
12+
}
13+
14+
interface Foo<T extends Foo<T>> {
15+
>Foo : Symbol(Foo, Decl(recurringTypeParamForContainerOfBase01.ts, 3, 1))
16+
>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 5, 14))
17+
>Foo : Symbol(Foo, Decl(recurringTypeParamForContainerOfBase01.ts, 3, 1))
18+
>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 5, 14))
19+
20+
self: T;
21+
>self : Symbol(Foo.self, Decl(recurringTypeParamForContainerOfBase01.ts, 5, 33))
22+
>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 5, 14))
23+
}
24+
25+
interface Bar<T extends Bar<T>> extends Foo<T> {
26+
>Bar : Symbol(Bar, Decl(recurringTypeParamForContainerOfBase01.ts, 7, 1))
27+
>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 9, 14))
28+
>Bar : Symbol(Bar, Decl(recurringTypeParamForContainerOfBase01.ts, 7, 1))
29+
>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 9, 14))
30+
>Foo : Symbol(Foo, Decl(recurringTypeParamForContainerOfBase01.ts, 3, 1))
31+
>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 9, 14))
32+
33+
other: BoxOfFoo<T>;
34+
>other : Symbol(Bar.other, Decl(recurringTypeParamForContainerOfBase01.ts, 9, 48))
35+
>BoxOfFoo : Symbol(BoxOfFoo, Decl(recurringTypeParamForContainerOfBase01.ts, 0, 0))
36+
>T : Symbol(T, Decl(recurringTypeParamForContainerOfBase01.ts, 9, 14))
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
=== tests/cases/conformance/types/typeParameters/recurringTypeParamForContainerOfBase01.ts ===
2+
3+
interface BoxOfFoo<T extends Foo<T>> {
4+
>BoxOfFoo : BoxOfFoo<T>
5+
>T : T
6+
>Foo : Foo<T>
7+
>T : T
8+
9+
item: T
10+
>item : T
11+
>T : T
12+
}
13+
14+
interface Foo<T extends Foo<T>> {
15+
>Foo : Foo<T>
16+
>T : T
17+
>Foo : Foo<T>
18+
>T : T
19+
20+
self: T;
21+
>self : T
22+
>T : T
23+
}
24+
25+
interface Bar<T extends Bar<T>> extends Foo<T> {
26+
>Bar : Bar<T>
27+
>T : T
28+
>Bar : Bar<T>
29+
>T : T
30+
>Foo : Foo<T>
31+
>T : T
32+
33+
other: BoxOfFoo<T>;
34+
>other : BoxOfFoo<T>
35+
>BoxOfFoo : BoxOfFoo<T>
36+
>T : T
37+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//// [thisTypeInBasePropertyAndDerivedContainerOfBase01.ts]
2+
3+
interface BoxOfFoo<T extends Foo> {
4+
item: T
5+
}
6+
7+
interface Foo {
8+
self: this;
9+
}
10+
11+
interface Bar extends Foo {
12+
other: BoxOfFoo<this>;
13+
}
14+
15+
//// [thisTypeInBasePropertyAndDerivedContainerOfBase01.js]
16+
17+
18+
//// [thisTypeInBasePropertyAndDerivedContainerOfBase01.d.ts]
19+
interface BoxOfFoo<T extends Foo> {
20+
item: T;
21+
}
22+
interface Foo {
23+
self: this;
24+
}
25+
interface Bar extends Foo {
26+
other: BoxOfFoo<this>;
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== tests/cases/conformance/types/thisType/thisTypeInBasePropertyAndDerivedContainerOfBase01.ts ===
2+
3+
interface BoxOfFoo<T extends Foo> {
4+
>BoxOfFoo : Symbol(BoxOfFoo, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 0, 0))
5+
>T : Symbol(T, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 1, 19))
6+
>Foo : Symbol(Foo, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 3, 1))
7+
8+
item: T
9+
>item : Symbol(BoxOfFoo.item, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 1, 35))
10+
>T : Symbol(T, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 1, 19))
11+
}
12+
13+
interface Foo {
14+
>Foo : Symbol(Foo, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 3, 1))
15+
16+
self: this;
17+
>self : Symbol(Foo.self, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 5, 15))
18+
}
19+
20+
interface Bar extends Foo {
21+
>Bar : Symbol(Bar, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 7, 1))
22+
>Foo : Symbol(Foo, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 3, 1))
23+
24+
other: BoxOfFoo<this>;
25+
>other : Symbol(Bar.other, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 9, 27))
26+
>BoxOfFoo : Symbol(BoxOfFoo, Decl(thisTypeInBasePropertyAndDerivedContainerOfBase01.ts, 0, 0))
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== tests/cases/conformance/types/thisType/thisTypeInBasePropertyAndDerivedContainerOfBase01.ts ===
2+
3+
interface BoxOfFoo<T extends Foo> {
4+
>BoxOfFoo : BoxOfFoo<T>
5+
>T : T
6+
>Foo : Foo
7+
8+
item: T
9+
>item : T
10+
>T : T
11+
}
12+
13+
interface Foo {
14+
>Foo : Foo
15+
16+
self: this;
17+
>self : this
18+
}
19+
20+
interface Bar extends Foo {
21+
>Bar : Bar
22+
>Foo : Foo
23+
24+
other: BoxOfFoo<this>;
25+
>other : BoxOfFoo<this>
26+
>BoxOfFoo : BoxOfFoo<T>
27+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// @declaration: true
2+
3+
interface BoxOfFoo<T extends Foo> {
4+
item: T
5+
}
6+
7+
interface Foo {
8+
self: this;
9+
}
10+
11+
interface Bar extends Foo {
12+
other: BoxOfFoo<this>;
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// @declaration: true
2+
3+
interface BoxOfFoo<T extends Foo<T>> {
4+
item: T
5+
}
6+
7+
interface Foo<T extends Foo<T>> {
8+
self: T;
9+
}
10+
11+
interface Bar<T extends Bar<T>> extends Foo<T> {
12+
other: BoxOfFoo<T>;
13+
}

0 commit comments

Comments
 (0)