Skip to content

Commit b7fe99a

Browse files
authored
Instantiate constraint with default upon comparison (#31240)
1 parent ae3d1d4 commit b7fe99a

5 files changed

+203
-1
lines changed

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24441,7 +24441,7 @@ namespace ts {
2444124441
const constraintType = getConstraintOfTypeParameter(typeParameter);
2444224442
const defaultType = getDefaultFromTypeParameter(typeParameter);
2444324443
if (constraintType && defaultType) {
24444-
checkTypeAssignableTo(defaultType, getTypeWithThisArgument(constraintType, defaultType), node.default, Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
24444+
checkTypeAssignableTo(defaultType, getTypeWithThisArgument(instantiateType(constraintType, makeUnaryTypeMapper(typeParameter, defaultType)), defaultType), node.default, Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
2444524445
}
2444624446
if (produceDiagnostics) {
2444724447
checkTypeNameIsReserved(node.name, Diagnostics.Type_parameter_name_cannot_be_0);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//// [typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts]
2+
// tricky interface
3+
interface Settable<T, V> {
4+
set(value: V): T;
5+
}
6+
7+
// implement
8+
class Identity<V> implements Settable<Identity<V>, V> {
9+
readonly item: V;
10+
constructor(value: V) {
11+
this.item = value;
12+
}
13+
public set(value: V): Identity<V> {
14+
return new Identity<V>(value);
15+
}
16+
}
17+
18+
// generic parameter default
19+
interface Test1<V, T extends Settable<T, V> = Identity<V>> { };
20+
let test1: Test1<number>;
21+
22+
// not generic parameter default
23+
interface Test2Base<V, T extends Settable<T, V>> { };
24+
type Test2<V> = Test2Base<V, Identity<V>>;
25+
let test2: Test2<number>;
26+
27+
28+
//// [typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.js]
29+
// implement
30+
var Identity = /** @class */ (function () {
31+
function Identity(value) {
32+
this.item = value;
33+
}
34+
Identity.prototype.set = function (value) {
35+
return new Identity(value);
36+
};
37+
return Identity;
38+
}());
39+
;
40+
var test1;
41+
;
42+
var test2;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
=== tests/cases/compiler/typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts ===
2+
// tricky interface
3+
interface Settable<T, V> {
4+
>Settable : Symbol(Settable, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 0, 0))
5+
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 1, 19))
6+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 1, 21))
7+
8+
set(value: V): T;
9+
>set : Symbol(Settable.set, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 1, 26))
10+
>value : Symbol(value, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 2, 8))
11+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 1, 21))
12+
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 1, 19))
13+
}
14+
15+
// implement
16+
class Identity<V> implements Settable<Identity<V>, V> {
17+
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
18+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
19+
>Settable : Symbol(Settable, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 0, 0))
20+
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
21+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
22+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
23+
24+
readonly item: V;
25+
>item : Symbol(Identity.item, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 55))
26+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
27+
28+
constructor(value: V) {
29+
>value : Symbol(value, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 8, 16))
30+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
31+
32+
this.item = value;
33+
>this.item : Symbol(Identity.item, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 55))
34+
>this : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
35+
>item : Symbol(Identity.item, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 55))
36+
>value : Symbol(value, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 8, 16))
37+
}
38+
public set(value: V): Identity<V> {
39+
>set : Symbol(Identity.set, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 10, 5))
40+
>value : Symbol(value, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 11, 15))
41+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
42+
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
43+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
44+
45+
return new Identity<V>(value);
46+
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
47+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
48+
>value : Symbol(value, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 11, 15))
49+
}
50+
}
51+
52+
// generic parameter default
53+
interface Test1<V, T extends Settable<T, V> = Identity<V>> { };
54+
>Test1 : Symbol(Test1, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 14, 1))
55+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 17, 16))
56+
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 17, 18))
57+
>Settable : Symbol(Settable, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 0, 0))
58+
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 17, 18))
59+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 17, 16))
60+
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
61+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 17, 16))
62+
63+
let test1: Test1<number>;
64+
>test1 : Symbol(test1, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 18, 3))
65+
>Test1 : Symbol(Test1, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 14, 1))
66+
67+
// not generic parameter default
68+
interface Test2Base<V, T extends Settable<T, V>> { };
69+
>Test2Base : Symbol(Test2Base, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 18, 25))
70+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 20))
71+
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 22))
72+
>Settable : Symbol(Settable, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 0, 0))
73+
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 22))
74+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 20))
75+
76+
type Test2<V> = Test2Base<V, Identity<V>>;
77+
>Test2 : Symbol(Test2, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 53))
78+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 22, 11))
79+
>Test2Base : Symbol(Test2Base, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 18, 25))
80+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 22, 11))
81+
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
82+
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 22, 11))
83+
84+
let test2: Test2<number>;
85+
>test2 : Symbol(test2, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 23, 3))
86+
>Test2 : Symbol(Test2, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 53))
87+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
=== tests/cases/compiler/typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts ===
2+
// tricky interface
3+
interface Settable<T, V> {
4+
set(value: V): T;
5+
>set : (value: V) => T
6+
>value : V
7+
}
8+
9+
// implement
10+
class Identity<V> implements Settable<Identity<V>, V> {
11+
>Identity : Identity<V>
12+
13+
readonly item: V;
14+
>item : V
15+
16+
constructor(value: V) {
17+
>value : V
18+
19+
this.item = value;
20+
>this.item = value : V
21+
>this.item : V
22+
>this : this
23+
>item : V
24+
>value : V
25+
}
26+
public set(value: V): Identity<V> {
27+
>set : (value: V) => Identity<V>
28+
>value : V
29+
30+
return new Identity<V>(value);
31+
>new Identity<V>(value) : Identity<V>
32+
>Identity : typeof Identity
33+
>value : V
34+
}
35+
}
36+
37+
// generic parameter default
38+
interface Test1<V, T extends Settable<T, V> = Identity<V>> { };
39+
let test1: Test1<number>;
40+
>test1 : Test1<number, Identity<number>>
41+
42+
// not generic parameter default
43+
interface Test2Base<V, T extends Settable<T, V>> { };
44+
type Test2<V> = Test2Base<V, Identity<V>>;
45+
>Test2 : Test2Base<V, Identity<V>>
46+
47+
let test2: Test2<number>;
48+
>test2 : Test2Base<number, Identity<number>>
49+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// tricky interface
2+
interface Settable<T, V> {
3+
set(value: V): T;
4+
}
5+
6+
// implement
7+
class Identity<V> implements Settable<Identity<V>, V> {
8+
readonly item: V;
9+
constructor(value: V) {
10+
this.item = value;
11+
}
12+
public set(value: V): Identity<V> {
13+
return new Identity<V>(value);
14+
}
15+
}
16+
17+
// generic parameter default
18+
interface Test1<V, T extends Settable<T, V> = Identity<V>> { };
19+
let test1: Test1<number>;
20+
21+
// not generic parameter default
22+
interface Test2Base<V, T extends Settable<T, V>> { };
23+
type Test2<V> = Test2Base<V, Identity<V>>;
24+
let test2: Test2<number>;

0 commit comments

Comments
 (0)