Skip to content

Commit 7eb1268

Browse files
committed
Get constraint with this argument of the type parameter for comparisons
1 parent 639b278 commit 7eb1268

File tree

6 files changed

+248
-2
lines changed

6 files changed

+248
-2
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9647,6 +9647,9 @@ namespace ts {
96479647

96489648
if (source.flags & TypeFlags.TypeParameter) {
96499649
let constraint = getConstraintOfTypeParameter(<TypeParameter>source);
9650+
if (constraint) {
9651+
constraint = getTypeWithThisArgument(constraint, source);
9652+
}
96509653
// A type parameter with no constraint is not related to the non-primitive object type.
96519654
if (constraint || !(target.flags & TypeFlags.NonPrimitive)) {
96529655
if (!constraint || constraint.flags & TypeFlags.Any) {
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//// [collectionPatternNoError.ts]
2+
interface MsgConstructor<T extends Message> {
3+
new(data: Array<{}>): T;
4+
}
5+
class Message {
6+
clone(): this {
7+
return this;
8+
}
9+
}
10+
interface MessageList<T extends Message> extends Message {
11+
methodOnMessageList(): T[];
12+
}
13+
14+
function fetchMsg<V extends Message>(protoCtor: MsgConstructor<V>): V {
15+
return null!;
16+
}
17+
18+
class DataProvider<T extends Message, U extends MessageList<T>> {
19+
constructor(
20+
private readonly message: MsgConstructor<T>,
21+
private readonly messageList: MsgConstructor<U>,
22+
) {}
23+
24+
fetch() {
25+
const messageList = fetchMsg(this.messageList);
26+
messageList.methodOnMessageList();
27+
}
28+
}
29+
30+
//// [collectionPatternNoError.js]
31+
var Message = /** @class */ (function () {
32+
function Message() {
33+
}
34+
Message.prototype.clone = function () {
35+
return this;
36+
};
37+
return Message;
38+
}());
39+
function fetchMsg(protoCtor) {
40+
return null;
41+
}
42+
var DataProvider = /** @class */ (function () {
43+
function DataProvider(message, messageList) {
44+
this.message = message;
45+
this.messageList = messageList;
46+
}
47+
DataProvider.prototype.fetch = function () {
48+
var messageList = fetchMsg(this.messageList);
49+
messageList.methodOnMessageList();
50+
};
51+
return DataProvider;
52+
}());
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
=== tests/cases/compiler/collectionPatternNoError.ts ===
2+
interface MsgConstructor<T extends Message> {
3+
>MsgConstructor : Symbol(MsgConstructor, Decl(collectionPatternNoError.ts, 0, 0))
4+
>T : Symbol(T, Decl(collectionPatternNoError.ts, 0, 25))
5+
>Message : Symbol(Message, Decl(collectionPatternNoError.ts, 2, 3))
6+
7+
new(data: Array<{}>): T;
8+
>data : Symbol(data, Decl(collectionPatternNoError.ts, 1, 8))
9+
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
10+
>T : Symbol(T, Decl(collectionPatternNoError.ts, 0, 25))
11+
}
12+
class Message {
13+
>Message : Symbol(Message, Decl(collectionPatternNoError.ts, 2, 3))
14+
15+
clone(): this {
16+
>clone : Symbol(Message.clone, Decl(collectionPatternNoError.ts, 3, 17))
17+
18+
return this;
19+
>this : Symbol(Message, Decl(collectionPatternNoError.ts, 2, 3))
20+
}
21+
}
22+
interface MessageList<T extends Message> extends Message {
23+
>MessageList : Symbol(MessageList, Decl(collectionPatternNoError.ts, 7, 3))
24+
>T : Symbol(T, Decl(collectionPatternNoError.ts, 8, 24))
25+
>Message : Symbol(Message, Decl(collectionPatternNoError.ts, 2, 3))
26+
>Message : Symbol(Message, Decl(collectionPatternNoError.ts, 2, 3))
27+
28+
methodOnMessageList(): T[];
29+
>methodOnMessageList : Symbol(MessageList.methodOnMessageList, Decl(collectionPatternNoError.ts, 8, 60))
30+
>T : Symbol(T, Decl(collectionPatternNoError.ts, 8, 24))
31+
}
32+
33+
function fetchMsg<V extends Message>(protoCtor: MsgConstructor<V>): V {
34+
>fetchMsg : Symbol(fetchMsg, Decl(collectionPatternNoError.ts, 10, 3))
35+
>V : Symbol(V, Decl(collectionPatternNoError.ts, 12, 20))
36+
>Message : Symbol(Message, Decl(collectionPatternNoError.ts, 2, 3))
37+
>protoCtor : Symbol(protoCtor, Decl(collectionPatternNoError.ts, 12, 39))
38+
>MsgConstructor : Symbol(MsgConstructor, Decl(collectionPatternNoError.ts, 0, 0))
39+
>V : Symbol(V, Decl(collectionPatternNoError.ts, 12, 20))
40+
>V : Symbol(V, Decl(collectionPatternNoError.ts, 12, 20))
41+
42+
return null!;
43+
}
44+
45+
class DataProvider<T extends Message, U extends MessageList<T>> {
46+
>DataProvider : Symbol(DataProvider, Decl(collectionPatternNoError.ts, 14, 3))
47+
>T : Symbol(T, Decl(collectionPatternNoError.ts, 16, 21))
48+
>Message : Symbol(Message, Decl(collectionPatternNoError.ts, 2, 3))
49+
>U : Symbol(U, Decl(collectionPatternNoError.ts, 16, 39))
50+
>MessageList : Symbol(MessageList, Decl(collectionPatternNoError.ts, 7, 3))
51+
>T : Symbol(T, Decl(collectionPatternNoError.ts, 16, 21))
52+
53+
constructor(
54+
private readonly message: MsgConstructor<T>,
55+
>message : Symbol(DataProvider.message, Decl(collectionPatternNoError.ts, 17, 16))
56+
>MsgConstructor : Symbol(MsgConstructor, Decl(collectionPatternNoError.ts, 0, 0))
57+
>T : Symbol(T, Decl(collectionPatternNoError.ts, 16, 21))
58+
59+
private readonly messageList: MsgConstructor<U>,
60+
>messageList : Symbol(DataProvider.messageList, Decl(collectionPatternNoError.ts, 18, 52))
61+
>MsgConstructor : Symbol(MsgConstructor, Decl(collectionPatternNoError.ts, 0, 0))
62+
>U : Symbol(U, Decl(collectionPatternNoError.ts, 16, 39))
63+
64+
) {}
65+
66+
fetch() {
67+
>fetch : Symbol(DataProvider.fetch, Decl(collectionPatternNoError.ts, 20, 8))
68+
69+
const messageList = fetchMsg(this.messageList);
70+
>messageList : Symbol(messageList, Decl(collectionPatternNoError.ts, 23, 11))
71+
>fetchMsg : Symbol(fetchMsg, Decl(collectionPatternNoError.ts, 10, 3))
72+
>this.messageList : Symbol(DataProvider.messageList, Decl(collectionPatternNoError.ts, 18, 52))
73+
>this : Symbol(DataProvider, Decl(collectionPatternNoError.ts, 14, 3))
74+
>messageList : Symbol(DataProvider.messageList, Decl(collectionPatternNoError.ts, 18, 52))
75+
76+
messageList.methodOnMessageList();
77+
>messageList.methodOnMessageList : Symbol(MessageList.methodOnMessageList, Decl(collectionPatternNoError.ts, 8, 60))
78+
>messageList : Symbol(messageList, Decl(collectionPatternNoError.ts, 23, 11))
79+
>methodOnMessageList : Symbol(MessageList.methodOnMessageList, Decl(collectionPatternNoError.ts, 8, 60))
80+
}
81+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
=== tests/cases/compiler/collectionPatternNoError.ts ===
2+
interface MsgConstructor<T extends Message> {
3+
>MsgConstructor : MsgConstructor<T>
4+
>T : T
5+
>Message : Message
6+
7+
new(data: Array<{}>): T;
8+
>data : {}[]
9+
>Array : T[]
10+
>T : T
11+
}
12+
class Message {
13+
>Message : Message
14+
15+
clone(): this {
16+
>clone : () => this
17+
18+
return this;
19+
>this : this
20+
}
21+
}
22+
interface MessageList<T extends Message> extends Message {
23+
>MessageList : MessageList<T>
24+
>T : T
25+
>Message : Message
26+
>Message : Message
27+
28+
methodOnMessageList(): T[];
29+
>methodOnMessageList : () => T[]
30+
>T : T
31+
}
32+
33+
function fetchMsg<V extends Message>(protoCtor: MsgConstructor<V>): V {
34+
>fetchMsg : <V extends Message>(protoCtor: MsgConstructor<V>) => V
35+
>V : V
36+
>Message : Message
37+
>protoCtor : MsgConstructor<V>
38+
>MsgConstructor : MsgConstructor<T>
39+
>V : V
40+
>V : V
41+
42+
return null!;
43+
>null! : null
44+
>null : null
45+
}
46+
47+
class DataProvider<T extends Message, U extends MessageList<T>> {
48+
>DataProvider : DataProvider<T, U>
49+
>T : T
50+
>Message : Message
51+
>U : U
52+
>MessageList : MessageList<T>
53+
>T : T
54+
55+
constructor(
56+
private readonly message: MsgConstructor<T>,
57+
>message : MsgConstructor<T>
58+
>MsgConstructor : MsgConstructor<T>
59+
>T : T
60+
61+
private readonly messageList: MsgConstructor<U>,
62+
>messageList : MsgConstructor<U>
63+
>MsgConstructor : MsgConstructor<T>
64+
>U : U
65+
66+
) {}
67+
68+
fetch() {
69+
>fetch : () => void
70+
71+
const messageList = fetchMsg(this.messageList);
72+
>messageList : U
73+
>fetchMsg(this.messageList) : U
74+
>fetchMsg : <V extends Message>(protoCtor: MsgConstructor<V>) => V
75+
>this.messageList : MsgConstructor<U>
76+
>this : this
77+
>messageList : MsgConstructor<U>
78+
79+
messageList.methodOnMessageList();
80+
>messageList.methodOnMessageList() : T[]
81+
>messageList.methodOnMessageList : () => T[]
82+
>messageList : U
83+
>methodOnMessageList : () => T[]
84+
}
85+
}

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,13): 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+
interface MsgConstructor<T extends Message> {
2+
new(data: Array<{}>): T;
3+
}
4+
class Message {
5+
clone(): this {
6+
return this;
7+
}
8+
}
9+
interface MessageList<T extends Message> extends Message {
10+
methodOnMessageList(): T[];
11+
}
12+
13+
function fetchMsg<V extends Message>(protoCtor: MsgConstructor<V>): V {
14+
return null!;
15+
}
16+
17+
class DataProvider<T extends Message, U extends MessageList<T>> {
18+
constructor(
19+
private readonly message: MsgConstructor<T>,
20+
private readonly messageList: MsgConstructor<U>,
21+
) {}
22+
23+
fetch() {
24+
const messageList = fetchMsg(this.messageList);
25+
messageList.methodOnMessageList();
26+
}
27+
}

0 commit comments

Comments
 (0)