mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 11:35:42 -06:00
Fix comparability between type parameters related by a union constraint (#50978)
This commit is contained in:
parent
b09e93d3f6
commit
fbfe9340a9
@ -19734,7 +19734,7 @@ namespace ts {
|
||||
// with another type parameter unless one extends the other. (Remember: comparability is mostly bidirectional!)
|
||||
let constraint = getConstraintOfTypeParameter(source);
|
||||
if (constraint && hasNonCircularBaseConstraint(source)) {
|
||||
while (constraint && constraint.flags & TypeFlags.TypeParameter) {
|
||||
while (constraint && someType(constraint, c => !!(c.flags & TypeFlags.TypeParameter))) {
|
||||
if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
//// [comparabilityTypeParametersRelatedByUnion.ts]
|
||||
class C<T> {
|
||||
constructor(readonly x: T) {}
|
||||
|
||||
good<U extends T>(y: U) {
|
||||
if (y === this.x) {}
|
||||
}
|
||||
|
||||
bad<U extends T | string>(y: U) {
|
||||
if (y === this.x) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [comparabilityTypeParametersRelatedByUnion.js]
|
||||
var C = /** @class */ (function () {
|
||||
function C(x) {
|
||||
this.x = x;
|
||||
}
|
||||
C.prototype.good = function (y) {
|
||||
if (y === this.x) { }
|
||||
};
|
||||
C.prototype.bad = function (y) {
|
||||
if (y === this.x) { }
|
||||
};
|
||||
return C;
|
||||
}());
|
||||
@ -0,0 +1,38 @@
|
||||
=== tests/cases/compiler/comparabilityTypeParametersRelatedByUnion.ts ===
|
||||
class C<T> {
|
||||
>C : Symbol(C, Decl(comparabilityTypeParametersRelatedByUnion.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(comparabilityTypeParametersRelatedByUnion.ts, 0, 8))
|
||||
|
||||
constructor(readonly x: T) {}
|
||||
>x : Symbol(C.x, Decl(comparabilityTypeParametersRelatedByUnion.ts, 1, 14))
|
||||
>T : Symbol(T, Decl(comparabilityTypeParametersRelatedByUnion.ts, 0, 8))
|
||||
|
||||
good<U extends T>(y: U) {
|
||||
>good : Symbol(C.good, Decl(comparabilityTypeParametersRelatedByUnion.ts, 1, 31))
|
||||
>U : Symbol(U, Decl(comparabilityTypeParametersRelatedByUnion.ts, 3, 7))
|
||||
>T : Symbol(T, Decl(comparabilityTypeParametersRelatedByUnion.ts, 0, 8))
|
||||
>y : Symbol(y, Decl(comparabilityTypeParametersRelatedByUnion.ts, 3, 20))
|
||||
>U : Symbol(U, Decl(comparabilityTypeParametersRelatedByUnion.ts, 3, 7))
|
||||
|
||||
if (y === this.x) {}
|
||||
>y : Symbol(y, Decl(comparabilityTypeParametersRelatedByUnion.ts, 3, 20))
|
||||
>this.x : Symbol(C.x, Decl(comparabilityTypeParametersRelatedByUnion.ts, 1, 14))
|
||||
>this : Symbol(C, Decl(comparabilityTypeParametersRelatedByUnion.ts, 0, 0))
|
||||
>x : Symbol(C.x, Decl(comparabilityTypeParametersRelatedByUnion.ts, 1, 14))
|
||||
}
|
||||
|
||||
bad<U extends T | string>(y: U) {
|
||||
>bad : Symbol(C.bad, Decl(comparabilityTypeParametersRelatedByUnion.ts, 5, 3))
|
||||
>U : Symbol(U, Decl(comparabilityTypeParametersRelatedByUnion.ts, 7, 6))
|
||||
>T : Symbol(T, Decl(comparabilityTypeParametersRelatedByUnion.ts, 0, 8))
|
||||
>y : Symbol(y, Decl(comparabilityTypeParametersRelatedByUnion.ts, 7, 28))
|
||||
>U : Symbol(U, Decl(comparabilityTypeParametersRelatedByUnion.ts, 7, 6))
|
||||
|
||||
if (y === this.x) {}
|
||||
>y : Symbol(y, Decl(comparabilityTypeParametersRelatedByUnion.ts, 7, 28))
|
||||
>this.x : Symbol(C.x, Decl(comparabilityTypeParametersRelatedByUnion.ts, 1, 14))
|
||||
>this : Symbol(C, Decl(comparabilityTypeParametersRelatedByUnion.ts, 0, 0))
|
||||
>x : Symbol(C.x, Decl(comparabilityTypeParametersRelatedByUnion.ts, 1, 14))
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
=== tests/cases/compiler/comparabilityTypeParametersRelatedByUnion.ts ===
|
||||
class C<T> {
|
||||
>C : C<T>
|
||||
|
||||
constructor(readonly x: T) {}
|
||||
>x : T
|
||||
|
||||
good<U extends T>(y: U) {
|
||||
>good : <U extends T>(y: U) => void
|
||||
>y : U
|
||||
|
||||
if (y === this.x) {}
|
||||
>y === this.x : boolean
|
||||
>y : U
|
||||
>this.x : T
|
||||
>this : this
|
||||
>x : T
|
||||
}
|
||||
|
||||
bad<U extends T | string>(y: U) {
|
||||
>bad : <U extends string | T>(y: U) => void
|
||||
>y : U
|
||||
|
||||
if (y === this.x) {}
|
||||
>y === this.x : boolean
|
||||
>y : U
|
||||
>this.x : T
|
||||
>this : this
|
||||
>x : T
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
class C<T> {
|
||||
constructor(readonly x: T) {}
|
||||
|
||||
good<U extends T>(y: U) {
|
||||
if (y === this.x) {}
|
||||
}
|
||||
|
||||
bad<U extends T | string>(y: U) {
|
||||
if (y === this.x) {}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user