Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Instantiate constraint with default upon comparison (#31240)
  • Loading branch information
weswigham committed May 11, 2019
1 parent ae3d1d4 commit b7fe99a
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Expand Up @@ -24441,7 +24441,7 @@ namespace ts {
const constraintType = getConstraintOfTypeParameter(typeParameter);
const defaultType = getDefaultFromTypeParameter(typeParameter);
if (constraintType && defaultType) {
checkTypeAssignableTo(defaultType, getTypeWithThisArgument(constraintType, defaultType), node.default, Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
checkTypeAssignableTo(defaultType, getTypeWithThisArgument(instantiateType(constraintType, makeUnaryTypeMapper(typeParameter, defaultType)), defaultType), node.default, Diagnostics.Type_0_does_not_satisfy_the_constraint_1);
}
if (produceDiagnostics) {
checkTypeNameIsReserved(node.name, Diagnostics.Type_parameter_name_cannot_be_0);
Expand Down
@@ -0,0 +1,42 @@
//// [typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts]
// tricky interface
interface Settable<T, V> {
set(value: V): T;
}

// implement
class Identity<V> implements Settable<Identity<V>, V> {
readonly item: V;
constructor(value: V) {
this.item = value;
}
public set(value: V): Identity<V> {
return new Identity<V>(value);
}
}

// generic parameter default
interface Test1<V, T extends Settable<T, V> = Identity<V>> { };
let test1: Test1<number>;

// not generic parameter default
interface Test2Base<V, T extends Settable<T, V>> { };
type Test2<V> = Test2Base<V, Identity<V>>;
let test2: Test2<number>;


//// [typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.js]
// implement
var Identity = /** @class */ (function () {
function Identity(value) {
this.item = value;
}
Identity.prototype.set = function (value) {
return new Identity(value);
};
return Identity;
}());
;
var test1;
;
var test2;
@@ -0,0 +1,87 @@
=== tests/cases/compiler/typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts ===
// tricky interface
interface Settable<T, V> {
>Settable : Symbol(Settable, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 0, 0))
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 1, 19))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 1, 21))

set(value: V): T;
>set : Symbol(Settable.set, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 1, 26))
>value : Symbol(value, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 2, 8))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 1, 21))
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 1, 19))
}

// implement
class Identity<V> implements Settable<Identity<V>, V> {
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
>Settable : Symbol(Settable, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 0, 0))
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))

readonly item: V;
>item : Symbol(Identity.item, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 55))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))

constructor(value: V) {
>value : Symbol(value, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 8, 16))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))

this.item = value;
>this.item : Symbol(Identity.item, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 55))
>this : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
>item : Symbol(Identity.item, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 55))
>value : Symbol(value, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 8, 16))
}
public set(value: V): Identity<V> {
>set : Symbol(Identity.set, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 10, 5))
>value : Symbol(value, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 11, 15))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))

return new Identity<V>(value);
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 6, 15))
>value : Symbol(value, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 11, 15))
}
}

// generic parameter default
interface Test1<V, T extends Settable<T, V> = Identity<V>> { };
>Test1 : Symbol(Test1, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 14, 1))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 17, 16))
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 17, 18))
>Settable : Symbol(Settable, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 0, 0))
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 17, 18))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 17, 16))
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 17, 16))

let test1: Test1<number>;
>test1 : Symbol(test1, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 18, 3))
>Test1 : Symbol(Test1, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 14, 1))

// not generic parameter default
interface Test2Base<V, T extends Settable<T, V>> { };
>Test2Base : Symbol(Test2Base, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 18, 25))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 20))
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 22))
>Settable : Symbol(Settable, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 0, 0))
>T : Symbol(T, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 22))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 20))

type Test2<V> = Test2Base<V, Identity<V>>;
>Test2 : Symbol(Test2, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 53))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 22, 11))
>Test2Base : Symbol(Test2Base, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 18, 25))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 22, 11))
>Identity : Symbol(Identity, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 3, 1))
>V : Symbol(V, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 22, 11))

let test2: Test2<number>;
>test2 : Symbol(test2, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 23, 3))
>Test2 : Symbol(Test2, Decl(typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts, 21, 53))

@@ -0,0 +1,49 @@
=== tests/cases/compiler/typePartameterConstraintInstantiatedWithDefaultWhenCheckingDefault.ts ===
// tricky interface
interface Settable<T, V> {
set(value: V): T;
>set : (value: V) => T
>value : V
}

// implement
class Identity<V> implements Settable<Identity<V>, V> {
>Identity : Identity<V>

readonly item: V;
>item : V

constructor(value: V) {
>value : V

this.item = value;
>this.item = value : V
>this.item : V
>this : this
>item : V
>value : V
}
public set(value: V): Identity<V> {
>set : (value: V) => Identity<V>
>value : V

return new Identity<V>(value);
>new Identity<V>(value) : Identity<V>
>Identity : typeof Identity
>value : V
}
}

// generic parameter default
interface Test1<V, T extends Settable<T, V> = Identity<V>> { };
let test1: Test1<number>;
>test1 : Test1<number, Identity<number>>

// not generic parameter default
interface Test2Base<V, T extends Settable<T, V>> { };
type Test2<V> = Test2Base<V, Identity<V>>;
>Test2 : Test2Base<V, Identity<V>>

let test2: Test2<number>;
>test2 : Test2Base<number, Identity<number>>

@@ -0,0 +1,24 @@
// tricky interface
interface Settable<T, V> {
set(value: V): T;
}

// implement
class Identity<V> implements Settable<Identity<V>, V> {
readonly item: V;
constructor(value: V) {
this.item = value;
}
public set(value: V): Identity<V> {
return new Identity<V>(value);
}
}

// generic parameter default
interface Test1<V, T extends Settable<T, V> = Identity<V>> { };
let test1: Test1<number>;

// not generic parameter default
interface Test2Base<V, T extends Settable<T, V>> { };
type Test2<V> = Test2Base<V, Identity<V>>;
let test2: Test2<number>;

0 comments on commit b7fe99a

Please sign in to comment.