diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7cde9314450eb..25a34b894cd59 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -24887,12 +24887,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // This like getBaseTypeOfLiteralType, but instead treats enum literals as strings/numbers instead // of returning their enum base type (which depends on the types of other literals in the enum). - function getBaseTypeOfLiteralTypeForComparison(type: Type): Type { - return type.flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ? stringType : + // It also checks if the type used in the comparison may be undefined or null (or is unknown/unconstrained) + function getBaseTypeForComparison(type: Type): Type { + return type.flags & TypeFlags.Instantiable && strictNullChecks ? getBaseConstraintOfType(type) ?? unknownUnionType : + type.flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ? stringType : type.flags & (TypeFlags.NumberLiteral | TypeFlags.Enum) ? numberType : type.flags & TypeFlags.BigIntLiteral ? bigintType : type.flags & TypeFlags.BooleanLiteral ? booleanType : - type.flags & TypeFlags.Union ? mapType(type, getBaseTypeOfLiteralTypeForComparison) : + type.flags & TypeFlags.Union ? mapType(type, getBaseTypeForComparison) : + type.flags & TypeFlags.Intersection && every((type as IntersectionType).types, t => { + return getBaseTypeForComparison(t) === unknownUnionType; + }) ? unknownUnionType : type; } @@ -39677,8 +39682,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.LessThanEqualsToken: case SyntaxKind.GreaterThanEqualsToken: if (checkForDisallowedESSymbolOperand(operator)) { - leftType = getBaseTypeOfLiteralTypeForComparison(checkNonNullType(leftType, left)); - rightType = getBaseTypeOfLiteralTypeForComparison(checkNonNullType(rightType, right)); + leftType = checkNonNullType(getBaseTypeForComparison(leftType), left); + rightType = checkNonNullType(getBaseTypeForComparison(rightType), right); reportOperatorErrorUnless((left, right) => { if (isTypeAny(left) || isTypeAny(right)) { return true; diff --git a/tests/baselines/reference/unconstrainedTypeComparison.errors.txt b/tests/baselines/reference/unconstrainedTypeComparison.errors.txt new file mode 100644 index 0000000000000..445c740f60d6a --- /dev/null +++ b/tests/baselines/reference/unconstrainedTypeComparison.errors.txt @@ -0,0 +1,185 @@ +unconstrainedTypeComparison.ts(2,12): error TS18049: 'a' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(2,16): error TS18049: 'b' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(6,12): error TS18049: 'a' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(6,16): error TS18049: 'b' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(10,12): error TS18046: 'a' is of type 'unknown'. +unconstrainedTypeComparison.ts(10,16): error TS18046: 'b' is of type 'unknown'. +unconstrainedTypeComparison.ts(14,12): error TS18049: 'a' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(14,16): error TS18049: 'b' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(18,12): error TS18049: 'a' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(18,16): error TS18049: 'b' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(22,12): error TS18046: 'a' is of type 'unknown'. +unconstrainedTypeComparison.ts(22,16): error TS18046: 'b' is of type 'unknown'. +unconstrainedTypeComparison.ts(26,12): error TS18048: 'a' is possibly 'undefined'. +unconstrainedTypeComparison.ts(26,16): error TS18048: 'b' is possibly 'undefined'. +unconstrainedTypeComparison.ts(30,12): error TS18047: 'a' is possibly 'null'. +unconstrainedTypeComparison.ts(30,16): error TS18047: 'b' is possibly 'null'. +unconstrainedTypeComparison.ts(34,12): error TS18049: 'a' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(34,16): error TS18049: 'b' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(38,12): error TS18049: 'x' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(38,16): error TS18049: 'y' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(42,12): error TS18049: 'x' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(42,16): error TS18049: 'y' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(49,12): error TS18047: 'x' is possibly 'null'. +unconstrainedTypeComparison.ts(49,16): error TS18049: 'y' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(56,12): error TS18047: 'x' is possibly 'null'. +unconstrainedTypeComparison.ts(56,16): error TS18049: 'y' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(60,12): error TS18049: 'x' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(60,16): error TS18049: 'y' is possibly 'null' or 'undefined'. +unconstrainedTypeComparison.ts(74,12): error TS18047: 'x' is possibly 'null'. +unconstrainedTypeComparison.ts(74,16): error TS18048: 'y' is possibly 'undefined'. +unconstrainedTypeComparison.ts(85,12): error TS18047: 'a' is possibly 'null'. +unconstrainedTypeComparison.ts(85,16): error TS18048: 'b' is possibly 'undefined'. + + +==== unconstrainedTypeComparison.ts (32 errors) ==== + function f1(a: T, b: T): boolean { + return a > b; + ~ +!!! error TS18049: 'a' is possibly 'null' or 'undefined'. + ~ +!!! error TS18049: 'b' is possibly 'null' or 'undefined'. + } + + function f2(a: T, b: T): boolean { + return a > b; + ~ +!!! error TS18049: 'a' is possibly 'null' or 'undefined'. + ~ +!!! error TS18049: 'b' is possibly 'null' or 'undefined'. + } + + function f3(a: T, b: T): boolean { + return a > b; + ~ +!!! error TS18046: 'a' is of type 'unknown'. + ~ +!!! error TS18046: 'b' is of type 'unknown'. + } + + function f4(a: U, b: U): boolean { + return a > b; + ~ +!!! error TS18049: 'a' is possibly 'null' or 'undefined'. + ~ +!!! error TS18049: 'b' is possibly 'null' or 'undefined'. + } + + function f5(a: U, b: U): boolean { + return a > b; + ~ +!!! error TS18049: 'a' is possibly 'null' or 'undefined'. + ~ +!!! error TS18049: 'b' is possibly 'null' or 'undefined'. + } + + function f6(a: U, b: U): boolean { + return a > b; + ~ +!!! error TS18046: 'a' is of type 'unknown'. + ~ +!!! error TS18046: 'b' is of type 'unknown'. + } + + function f7(a: U, b: U): boolean { + return a > b; + ~ +!!! error TS18048: 'a' is possibly 'undefined'. + ~ +!!! error TS18048: 'b' is possibly 'undefined'. + } + + function f8(a: U, b: U): boolean { + return a > b; + ~ +!!! error TS18047: 'a' is possibly 'null'. + ~ +!!! error TS18047: 'b' is possibly 'null'. + } + + function f9(a: U, b: U): boolean { + return a > b; + ~ +!!! error TS18049: 'a' is possibly 'null' or 'undefined'. + ~ +!!! error TS18049: 'b' is possibly 'null' or 'undefined'. + } + + function f10(x: T | U, y: T | U) { + return x < y; + ~ +!!! error TS18049: 'x' is possibly 'null' or 'undefined'. + ~ +!!! error TS18049: 'y' is possibly 'null' or 'undefined'. + } + + function f11(x: T | number, y: U | number) { + return x < y; + ~ +!!! error TS18049: 'x' is possibly 'null' or 'undefined'. + ~ +!!! error TS18049: 'y' is possibly 'null' or 'undefined'. + } + + function f12(x: T | number, y: U | number) { + if (x === undefined) { + return false; + } + return x < y; + ~ +!!! error TS18047: 'x' is possibly 'null'. + ~ +!!! error TS18049: 'y' is possibly 'null' or 'undefined'. + } + + function f13(x: U, y: U) { + if (x === undefined) { + return false; + } + return x < y; + ~ +!!! error TS18047: 'x' is possibly 'null'. + ~ +!!! error TS18049: 'y' is possibly 'null' or 'undefined'. + } + + function f14(x: T & U, y: T & U) { + return x < y; + ~ +!!! error TS18049: 'x' is possibly 'null' or 'undefined'. + ~ +!!! error TS18049: 'y' is possibly 'null' or 'undefined'. + } + + function f15(x: T & number, y: U & number) { + return x < y; + } + + function f16(x: T & U, y: U) { + if (x === undefined) { + return false; + } + if (y === null) { + return false; + } + return x < y; + ~ +!!! error TS18047: 'x' is possibly 'null'. + ~ +!!! error TS18048: 'y' is possibly 'undefined'. + } + + + function compare(a: T, b: T): boolean { + if (a === undefined) { + return false; + } + if (b === null) { + return false; + } + return a > b; + ~ +!!! error TS18047: 'a' is possibly 'null'. + ~ +!!! error TS18048: 'b' is possibly 'undefined'. + } \ No newline at end of file diff --git a/tests/baselines/reference/unconstrainedTypeComparison.symbols b/tests/baselines/reference/unconstrainedTypeComparison.symbols new file mode 100644 index 0000000000000..0a8a9a7a30d26 --- /dev/null +++ b/tests/baselines/reference/unconstrainedTypeComparison.symbols @@ -0,0 +1,287 @@ +//// [tests/cases/compiler/unconstrainedTypeComparison.ts] //// + +=== unconstrainedTypeComparison.ts === +function f1(a: T, b: T): boolean { +>f1 : Symbol(f1, Decl(unconstrainedTypeComparison.ts, 0, 0)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 0, 12)) +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 0, 15)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 0, 12)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 0, 20)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 0, 12)) + + return a > b; +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 0, 15)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 0, 20)) +} + +function f2(a: T, b: T): boolean { +>f2 : Symbol(f2, Decl(unconstrainedTypeComparison.ts, 2, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 4, 12)) +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 4, 45)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 4, 12)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 4, 50)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 4, 12)) + + return a > b; +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 4, 45)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 4, 50)) +} + +function f3(a: T, b: T): boolean { +>f3 : Symbol(f3, Decl(unconstrainedTypeComparison.ts, 6, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 8, 12)) +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 8, 31)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 8, 12)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 8, 36)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 8, 12)) + + return a > b; +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 8, 31)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 8, 36)) +} + +function f4(a: U, b: U): boolean { +>f4 : Symbol(f4, Decl(unconstrainedTypeComparison.ts, 10, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 12, 12)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 12, 14)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 12, 12)) +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 12, 28)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 12, 14)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 12, 33)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 12, 14)) + + return a > b; +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 12, 28)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 12, 33)) +} + +function f5(a: U, b: U): boolean { +>f5 : Symbol(f5, Decl(unconstrainedTypeComparison.ts, 14, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 16, 12)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 16, 44)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 16, 12)) +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 16, 58)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 16, 44)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 16, 63)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 16, 44)) + + return a > b; +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 16, 58)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 16, 63)) +} + +function f6(a: U, b: U): boolean { +>f6 : Symbol(f6, Decl(unconstrainedTypeComparison.ts, 18, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 20, 12)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 20, 30)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 20, 12)) +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 20, 44)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 20, 30)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 20, 49)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 20, 30)) + + return a > b; +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 20, 44)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 20, 49)) +} + +function f7(a: U, b: U): boolean { +>f7 : Symbol(f7, Decl(unconstrainedTypeComparison.ts, 22, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 24, 12)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 24, 37)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 24, 12)) +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 24, 51)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 24, 37)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 24, 56)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 24, 37)) + + return a > b; +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 24, 51)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 24, 56)) +} + +function f8(a: U, b: U): boolean { +>f8 : Symbol(f8, Decl(unconstrainedTypeComparison.ts, 26, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 28, 12)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 28, 32)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 28, 12)) +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 28, 46)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 28, 32)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 28, 51)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 28, 32)) + + return a > b; +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 28, 46)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 28, 51)) +} + +function f9(a: U, b: U): boolean { +>f9 : Symbol(f9, Decl(unconstrainedTypeComparison.ts, 30, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 32, 12)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 32, 39)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 32, 12)) +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 32, 53)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 32, 39)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 32, 58)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 32, 39)) + + return a > b; +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 32, 53)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 32, 58)) +} + +function f10(x: T | U, y: T | U) { +>f10 : Symbol(f10, Decl(unconstrainedTypeComparison.ts, 34, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 36, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 36, 15)) +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 36, 19)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 36, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 36, 15)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 36, 28)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 36, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 36, 15)) + + return x < y; +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 36, 19)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 36, 28)) +} + +function f11(x: T | number, y: U | number) { +>f11 : Symbol(f11, Decl(unconstrainedTypeComparison.ts, 38, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 40, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 40, 15)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 40, 13)) +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 40, 29)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 40, 13)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 40, 43)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 40, 15)) + + return x < y; +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 40, 29)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 40, 43)) +} + +function f12(x: T | number, y: U | number) { +>f12 : Symbol(f12, Decl(unconstrainedTypeComparison.ts, 42, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 44, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 44, 15)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 44, 13)) +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 44, 29)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 44, 13)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 44, 43)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 44, 15)) + + if (x === undefined) { +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 44, 29)) +>undefined : Symbol(undefined) + + return false; + } + return x < y; +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 44, 29)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 44, 43)) +} + +function f13(x: U, y: U) { +>f13 : Symbol(f13, Decl(unconstrainedTypeComparison.ts, 49, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 51, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 51, 15)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 51, 13)) +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 51, 38)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 51, 15)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 51, 43)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 51, 15)) + + if (x === undefined) { +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 51, 38)) +>undefined : Symbol(undefined) + + return false; + } + return x < y; +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 51, 38)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 51, 43)) +} + +function f14(x: T & U, y: T & U) { +>f14 : Symbol(f14, Decl(unconstrainedTypeComparison.ts, 56, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 58, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 58, 15)) +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 58, 19)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 58, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 58, 15)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 58, 28)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 58, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 58, 15)) + + return x < y; +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 58, 19)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 58, 28)) +} + +function f15(x: T & number, y: U & number) { +>f15 : Symbol(f15, Decl(unconstrainedTypeComparison.ts, 60, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 62, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 62, 15)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 62, 13)) +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 62, 29)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 62, 13)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 62, 43)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 62, 15)) + + return x < y; +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 62, 29)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 62, 43)) +} + +function f16(x: T & U, y: U) { +>f16 : Symbol(f16, Decl(unconstrainedTypeComparison.ts, 64, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 66, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 66, 15)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 66, 13)) +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 66, 29)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 66, 13)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 66, 15)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 66, 38)) +>U : Symbol(U, Decl(unconstrainedTypeComparison.ts, 66, 15)) + + if (x === undefined) { +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 66, 29)) +>undefined : Symbol(undefined) + + return false; + } + if (y === null) { +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 66, 38)) + + return false; + } + return x < y; +>x : Symbol(x, Decl(unconstrainedTypeComparison.ts, 66, 29)) +>y : Symbol(y, Decl(unconstrainedTypeComparison.ts, 66, 38)) +} + + +function compare(a: T, b: T): boolean { +>compare : Symbol(compare, Decl(unconstrainedTypeComparison.ts, 74, 1)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 77, 17)) +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 77, 20)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 77, 17)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 77, 25)) +>T : Symbol(T, Decl(unconstrainedTypeComparison.ts, 77, 17)) + + if (a === undefined) { +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 77, 20)) +>undefined : Symbol(undefined) + + return false; + } + if (b === null) { +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 77, 25)) + + return false; + } + return a > b; +>a : Symbol(a, Decl(unconstrainedTypeComparison.ts, 77, 20)) +>b : Symbol(b, Decl(unconstrainedTypeComparison.ts, 77, 25)) +} diff --git a/tests/baselines/reference/unconstrainedTypeComparison.types b/tests/baselines/reference/unconstrainedTypeComparison.types new file mode 100644 index 0000000000000..8f3808ddb7cad --- /dev/null +++ b/tests/baselines/reference/unconstrainedTypeComparison.types @@ -0,0 +1,360 @@ +//// [tests/cases/compiler/unconstrainedTypeComparison.ts] //// + +=== unconstrainedTypeComparison.ts === +function f1(a: T, b: T): boolean { +>f1 : (a: T, b: T) => boolean +> : ^ ^^ ^^ ^^ ^^ ^^^^^ +>a : T +> : ^ +>b : T +> : ^ + + return a > b; +>a > b : boolean +> : ^^^^^^^ +>a : T +> : ^ +>b : T +> : ^ +} + +function f2(a: T, b: T): boolean { +>f2 : (a: T, b: T) => boolean +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>a : T +> : ^ +>b : T +> : ^ + + return a > b; +>a > b : boolean +> : ^^^^^^^ +>a : T +> : ^ +>b : T +> : ^ +} + +function f3(a: T, b: T): boolean { +>f3 : (a: T, b: T) => boolean +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>a : T +> : ^ +>b : T +> : ^ + + return a > b; +>a > b : boolean +> : ^^^^^^^ +>a : T +> : ^ +>b : T +> : ^ +} + +function f4(a: U, b: U): boolean { +>f4 : (a: U, b: U) => boolean +> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>a : U +> : ^ +>b : U +> : ^ + + return a > b; +>a > b : boolean +> : ^^^^^^^ +>a : U +> : ^ +>b : U +> : ^ +} + +function f5(a: U, b: U): boolean { +>f5 : (a: U, b: U) => boolean +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>a : U +> : ^ +>b : U +> : ^ + + return a > b; +>a > b : boolean +> : ^^^^^^^ +>a : U +> : ^ +>b : U +> : ^ +} + +function f6(a: U, b: U): boolean { +>f6 : (a: U, b: U) => boolean +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>a : U +> : ^ +>b : U +> : ^ + + return a > b; +>a > b : boolean +> : ^^^^^^^ +>a : U +> : ^ +>b : U +> : ^ +} + +function f7(a: U, b: U): boolean { +>f7 : (a: U, b: U) => boolean +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>a : U +> : ^ +>b : U +> : ^ + + return a > b; +>a > b : boolean +> : ^^^^^^^ +>a : U +> : ^ +>b : U +> : ^ +} + +function f8(a: U, b: U): boolean { +>f8 : (a: U, b: U) => boolean +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>a : U +> : ^ +>b : U +> : ^ + + return a > b; +>a > b : boolean +> : ^^^^^^^ +>a : U +> : ^ +>b : U +> : ^ +} + +function f9(a: U, b: U): boolean { +>f9 : (a: U, b: U) => boolean +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^ +>a : U +> : ^ +>b : U +> : ^ + + return a > b; +>a > b : boolean +> : ^^^^^^^ +>a : U +> : ^ +>b : U +> : ^ +} + +function f10(x: T | U, y: T | U) { +>f10 : (x: T | U, y: T | U) => boolean +> : ^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^ +>x : T | U +> : ^^^^^ +>y : T | U +> : ^^^^^ + + return x < y; +>x < y : boolean +> : ^^^^^^^ +>x : T | U +> : ^^^^^ +>y : T | U +> : ^^^^^ +} + +function f11(x: T | number, y: U | number) { +>f11 : (x: T | number, y: U | number) => boolean +> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^ +>x : number | T +> : ^^^^^^^^^^ +>y : number | U +> : ^^^^^^^^^^ + + return x < y; +>x < y : boolean +> : ^^^^^^^ +>x : number | T +> : ^^^^^^^^^^ +>y : number | U +> : ^^^^^^^^^^ +} + +function f12(x: T | number, y: U | number) { +>f12 : (x: T | number, y: U | number) => boolean +> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^ +>x : number | T +> : ^^^^^^^^^^ +>y : number | U +> : ^^^^^^^^^^ + + if (x === undefined) { +>x === undefined : boolean +> : ^^^^^^^ +>x : number | T +> : ^^^^^^^^^^ +>undefined : undefined +> : ^^^^^^^^^ + + return false; +>false : false +> : ^^^^^ + } + return x < y; +>x < y : boolean +> : ^^^^^^^ +>x : number | (T & ({} | null)) +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>y : number | U +> : ^^^^^^^^^^ +} + +function f13(x: U, y: U) { +>f13 : (x: U, y: U) => boolean +> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^ +>x : U +> : ^ +>y : U +> : ^ + + if (x === undefined) { +>x === undefined : boolean +> : ^^^^^^^ +>x : U +> : ^ +>undefined : undefined +> : ^^^^^^^^^ + + return false; +>false : false +> : ^^^^^ + } + return x < y; +>x < y : boolean +> : ^^^^^^^ +>x : U & ({} | null) +> : ^^^^^^^^^^^^^^^ +>y : U +> : ^ +} + +function f14(x: T & U, y: T & U) { +>f14 : (x: T & U, y: T & U) => boolean +> : ^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^ +>x : T & U +> : ^^^^^ +>y : T & U +> : ^^^^^ + + return x < y; +>x < y : boolean +> : ^^^^^^^ +>x : T & U +> : ^^^^^ +>y : T & U +> : ^^^^^ +} + +function f15(x: T & number, y: U & number) { +>f15 : (x: T & number, y: U & number) => boolean +> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^ +>x : T & number +> : ^^^^^^^^^^ +>y : U & number +> : ^^^^^^^^^^ + + return x < y; +>x < y : boolean +> : ^^^^^^^ +>x : T & number +> : ^^^^^^^^^^ +>y : U & number +> : ^^^^^^^^^^ +} + +function f16(x: T & U, y: U) { +>f16 : (x: T & U, y: U) => boolean +> : ^ ^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^ +>x : T & U +> : ^^^^^ +>y : U +> : ^ + + if (x === undefined) { +>x === undefined : boolean +> : ^^^^^^^ +>x : T & U +> : ^^^^^ +>undefined : undefined +> : ^^^^^^^^^ + + return false; +>false : false +> : ^^^^^ + } + if (y === null) { +>y === null : boolean +> : ^^^^^^^ +>y : U +> : ^ + + return false; +>false : false +> : ^^^^^ + } + return x < y; +>x < y : boolean +> : ^^^^^^^ +>x : T & U & ({} | null) +> : ^^^^^^^^^^^^^^^^^^^ +>y : U & ({} | undefined) +> : ^^^^^^^^^^^^^^^^^^^^ +} + + +function compare(a: T, b: T): boolean { +>compare : (a: T, b: T) => boolean +> : ^ ^^ ^^ ^^ ^^ ^^^^^ +>a : T +> : ^ +>b : T +> : ^ + + if (a === undefined) { +>a === undefined : boolean +> : ^^^^^^^ +>a : T +> : ^ +>undefined : undefined +> : ^^^^^^^^^ + + return false; +>false : false +> : ^^^^^ + } + if (b === null) { +>b === null : boolean +> : ^^^^^^^ +>b : T +> : ^ + + return false; +>false : false +> : ^^^^^ + } + return a > b; +>a > b : boolean +> : ^^^^^^^ +>a : T & ({} | null) +> : ^^^^^^^^^^^^^^^ +>b : T & ({} | undefined) +> : ^^^^^^^^^^^^^^^^^^^^ +} diff --git a/tests/cases/compiler/unconstrainedTypeComparison.ts b/tests/cases/compiler/unconstrainedTypeComparison.ts new file mode 100644 index 0000000000000..ad69988741917 --- /dev/null +++ b/tests/cases/compiler/unconstrainedTypeComparison.ts @@ -0,0 +1,90 @@ + +// @strict: true +// @noemit: true + +function f1(a: T, b: T): boolean { + return a > b; +} + +function f2(a: T, b: T): boolean { + return a > b; +} + +function f3(a: T, b: T): boolean { + return a > b; +} + +function f4(a: U, b: U): boolean { + return a > b; +} + +function f5(a: U, b: U): boolean { + return a > b; +} + +function f6(a: U, b: U): boolean { + return a > b; +} + +function f7(a: U, b: U): boolean { + return a > b; +} + +function f8(a: U, b: U): boolean { + return a > b; +} + +function f9(a: U, b: U): boolean { + return a > b; +} + +function f10(x: T | U, y: T | U) { + return x < y; +} + +function f11(x: T | number, y: U | number) { + return x < y; +} + +function f12(x: T | number, y: U | number) { + if (x === undefined) { + return false; + } + return x < y; +} + +function f13(x: U, y: U) { + if (x === undefined) { + return false; + } + return x < y; +} + +function f14(x: T & U, y: T & U) { + return x < y; +} + +function f15(x: T & number, y: U & number) { + return x < y; +} + +function f16(x: T & U, y: U) { + if (x === undefined) { + return false; + } + if (y === null) { + return false; + } + return x < y; +} + + +function compare(a: T, b: T): boolean { + if (a === undefined) { + return false; + } + if (b === null) { + return false; + } + return a > b; +} \ No newline at end of file