From acd8c77f4c4636b0aae7239b4f027afe99a6d307 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 16 Jul 2015 15:28:47 -0700 Subject: [PATCH] Accepting new baselines --- .../arrayOfFunctionTypes3.errors.txt | 35 ++ .../reference/arrayOfFunctionTypes3.symbols | 93 ---- .../reference/arrayOfFunctionTypes3.types | 116 ----- ...ualTypeWithUnionTypeCallSignatures.symbols | 2 - ...xtualTypeWithUnionTypeCallSignatures.types | 12 +- ...citTypeParameterAndArgumentType.errors.txt | 5 +- ...peGuardsInConditionalExpression.errors.txt | 103 +++++ .../typeGuardsInConditionalExpression.symbols | 251 ----------- .../typeGuardsInConditionalExpression.types | 388 ----------------- .../typeGuardsInIfStatement.errors.txt | 160 +++++++ .../reference/typeGuardsInIfStatement.symbols | 304 ------------- .../reference/typeGuardsInIfStatement.types | 405 ------------------ ...sInRightOperandOfAndAndOperator.errors.txt | 64 +++ ...ardsInRightOperandOfAndAndOperator.symbols | 143 ------- ...GuardsInRightOperandOfAndAndOperator.types | 234 ---------- ...rdsInRightOperandOfOrOrOperator.errors.txt | 64 +++ ...GuardsInRightOperandOfOrOrOperator.symbols | 143 ------- ...peGuardsInRightOperandOfOrOrOperator.types | 234 ---------- .../unionTypeCallSignatures.errors.txt | 15 +- .../unionTypeConstructSignatures.errors.txt | 15 +- 20 files changed, 448 insertions(+), 2338 deletions(-) create mode 100644 tests/baselines/reference/arrayOfFunctionTypes3.errors.txt delete mode 100644 tests/baselines/reference/arrayOfFunctionTypes3.symbols delete mode 100644 tests/baselines/reference/arrayOfFunctionTypes3.types create mode 100644 tests/baselines/reference/typeGuardsInConditionalExpression.errors.txt delete mode 100644 tests/baselines/reference/typeGuardsInConditionalExpression.symbols delete mode 100644 tests/baselines/reference/typeGuardsInConditionalExpression.types create mode 100644 tests/baselines/reference/typeGuardsInIfStatement.errors.txt delete mode 100644 tests/baselines/reference/typeGuardsInIfStatement.symbols delete mode 100644 tests/baselines/reference/typeGuardsInIfStatement.types create mode 100644 tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.errors.txt delete mode 100644 tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.symbols delete mode 100644 tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.types create mode 100644 tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.errors.txt delete mode 100644 tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.symbols delete mode 100644 tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.types diff --git a/tests/baselines/reference/arrayOfFunctionTypes3.errors.txt b/tests/baselines/reference/arrayOfFunctionTypes3.errors.txt new file mode 100644 index 00000000000..499d6bca387 --- /dev/null +++ b/tests/baselines/reference/arrayOfFunctionTypes3.errors.txt @@ -0,0 +1,35 @@ +tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayOfFunctionTypes3.ts(17,13): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayOfFunctionTypes3.ts(26,10): error TS2349: Cannot invoke an expression whose type lacks a call signature. + + +==== tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayOfFunctionTypes3.ts (2 errors) ==== + // valid uses of arrays of function types + + var x = [() => 1, () => { }]; + var r2 = x[0](); + + class C { + foo: string; + } + var y = [C, C]; + var r3 = new y[0](); + + var a: { (x: number): number; (x: string): string; }; + var b: { (x: number): number; (x: string): string; }; + var c: { (x: number): number; (x: any): any; }; + var z = [a, b, c]; + var r4 = z[0]; + var r5 = r4(''); // any not string + ~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + var r5b = r4(1); + + var a2: { (x: T): number; (x: string): string;}; + var b2: { (x: T): number; (x: string): string; }; + var c2: { (x: number): number; (x: T): any; }; + + var z2 = [a2, b2, c2]; + var r6 = z2[0]; + var r7 = r6(''); // any not string + ~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. \ No newline at end of file diff --git a/tests/baselines/reference/arrayOfFunctionTypes3.symbols b/tests/baselines/reference/arrayOfFunctionTypes3.symbols deleted file mode 100644 index d26effeb5b7..00000000000 --- a/tests/baselines/reference/arrayOfFunctionTypes3.symbols +++ /dev/null @@ -1,93 +0,0 @@ -=== tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayOfFunctionTypes3.ts === -// valid uses of arrays of function types - -var x = [() => 1, () => { }]; ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 2, 3)) - -var r2 = x[0](); ->r2 : Symbol(r2, Decl(arrayOfFunctionTypes3.ts, 3, 3)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 2, 3)) - -class C { ->C : Symbol(C, Decl(arrayOfFunctionTypes3.ts, 3, 16)) - - foo: string; ->foo : Symbol(foo, Decl(arrayOfFunctionTypes3.ts, 5, 9)) -} -var y = [C, C]; ->y : Symbol(y, Decl(arrayOfFunctionTypes3.ts, 8, 3)) ->C : Symbol(C, Decl(arrayOfFunctionTypes3.ts, 3, 16)) ->C : Symbol(C, Decl(arrayOfFunctionTypes3.ts, 3, 16)) - -var r3 = new y[0](); ->r3 : Symbol(r3, Decl(arrayOfFunctionTypes3.ts, 9, 3)) ->y : Symbol(y, Decl(arrayOfFunctionTypes3.ts, 8, 3)) - -var a: { (x: number): number; (x: string): string; }; ->a : Symbol(a, Decl(arrayOfFunctionTypes3.ts, 11, 3)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 11, 10)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 11, 31)) - -var b: { (x: number): number; (x: string): string; }; ->b : Symbol(b, Decl(arrayOfFunctionTypes3.ts, 12, 3)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 12, 10)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 12, 31)) - -var c: { (x: number): number; (x: any): any; }; ->c : Symbol(c, Decl(arrayOfFunctionTypes3.ts, 13, 3)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 13, 10)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 13, 31)) - -var z = [a, b, c]; ->z : Symbol(z, Decl(arrayOfFunctionTypes3.ts, 14, 3)) ->a : Symbol(a, Decl(arrayOfFunctionTypes3.ts, 11, 3)) ->b : Symbol(b, Decl(arrayOfFunctionTypes3.ts, 12, 3)) ->c : Symbol(c, Decl(arrayOfFunctionTypes3.ts, 13, 3)) - -var r4 = z[0]; ->r4 : Symbol(r4, Decl(arrayOfFunctionTypes3.ts, 15, 3)) ->z : Symbol(z, Decl(arrayOfFunctionTypes3.ts, 14, 3)) - -var r5 = r4(''); // any not string ->r5 : Symbol(r5, Decl(arrayOfFunctionTypes3.ts, 16, 3)) ->r4 : Symbol(r4, Decl(arrayOfFunctionTypes3.ts, 15, 3)) - -var r5b = r4(1); ->r5b : Symbol(r5b, Decl(arrayOfFunctionTypes3.ts, 17, 3)) ->r4 : Symbol(r4, Decl(arrayOfFunctionTypes3.ts, 15, 3)) - -var a2: { (x: T): number; (x: string): string;}; ->a2 : Symbol(a2, Decl(arrayOfFunctionTypes3.ts, 19, 3)) ->T : Symbol(T, Decl(arrayOfFunctionTypes3.ts, 19, 11)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 19, 14)) ->T : Symbol(T, Decl(arrayOfFunctionTypes3.ts, 19, 11)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 19, 30)) - -var b2: { (x: T): number; (x: string): string; }; ->b2 : Symbol(b2, Decl(arrayOfFunctionTypes3.ts, 20, 3)) ->T : Symbol(T, Decl(arrayOfFunctionTypes3.ts, 20, 11)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 20, 14)) ->T : Symbol(T, Decl(arrayOfFunctionTypes3.ts, 20, 11)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 20, 30)) - -var c2: { (x: number): number; (x: T): any; }; ->c2 : Symbol(c2, Decl(arrayOfFunctionTypes3.ts, 21, 3)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 21, 11)) ->T : Symbol(T, Decl(arrayOfFunctionTypes3.ts, 21, 32)) ->x : Symbol(x, Decl(arrayOfFunctionTypes3.ts, 21, 35)) ->T : Symbol(T, Decl(arrayOfFunctionTypes3.ts, 21, 32)) - -var z2 = [a2, b2, c2]; ->z2 : Symbol(z2, Decl(arrayOfFunctionTypes3.ts, 23, 3)) ->a2 : Symbol(a2, Decl(arrayOfFunctionTypes3.ts, 19, 3)) ->b2 : Symbol(b2, Decl(arrayOfFunctionTypes3.ts, 20, 3)) ->c2 : Symbol(c2, Decl(arrayOfFunctionTypes3.ts, 21, 3)) - -var r6 = z2[0]; ->r6 : Symbol(r6, Decl(arrayOfFunctionTypes3.ts, 24, 3)) ->z2 : Symbol(z2, Decl(arrayOfFunctionTypes3.ts, 23, 3)) - -var r7 = r6(''); // any not string ->r7 : Symbol(r7, Decl(arrayOfFunctionTypes3.ts, 25, 3)) ->r6 : Symbol(r6, Decl(arrayOfFunctionTypes3.ts, 24, 3)) - diff --git a/tests/baselines/reference/arrayOfFunctionTypes3.types b/tests/baselines/reference/arrayOfFunctionTypes3.types deleted file mode 100644 index b2378b3dc70..00000000000 --- a/tests/baselines/reference/arrayOfFunctionTypes3.types +++ /dev/null @@ -1,116 +0,0 @@ -=== tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayOfFunctionTypes3.ts === -// valid uses of arrays of function types - -var x = [() => 1, () => { }]; ->x : ((() => number) | (() => void))[] ->[() => 1, () => { }] : ((() => number) | (() => void))[] ->() => 1 : () => number ->1 : number ->() => { } : () => void - -var r2 = x[0](); ->r2 : void ->x[0]() : void ->x[0] : (() => number) | (() => void) ->x : ((() => number) | (() => void))[] ->0 : number - -class C { ->C : C - - foo: string; ->foo : string -} -var y = [C, C]; ->y : typeof C[] ->[C, C] : typeof C[] ->C : typeof C ->C : typeof C - -var r3 = new y[0](); ->r3 : C ->new y[0]() : C ->y[0] : typeof C ->y : typeof C[] ->0 : number - -var a: { (x: number): number; (x: string): string; }; ->a : { (x: number): number; (x: string): string; } ->x : number ->x : string - -var b: { (x: number): number; (x: string): string; }; ->b : { (x: number): number; (x: string): string; } ->x : number ->x : string - -var c: { (x: number): number; (x: any): any; }; ->c : { (x: number): number; (x: any): any; } ->x : number ->x : any - -var z = [a, b, c]; ->z : ({ (x: number): number; (x: string): string; } | { (x: number): number; (x: any): any; })[] ->[a, b, c] : ({ (x: number): number; (x: string): string; } | { (x: number): number; (x: any): any; })[] ->a : { (x: number): number; (x: string): string; } ->b : { (x: number): number; (x: string): string; } ->c : { (x: number): number; (x: any): any; } - -var r4 = z[0]; ->r4 : { (x: number): number; (x: string): string; } | { (x: number): number; (x: any): any; } ->z[0] : { (x: number): number; (x: string): string; } | { (x: number): number; (x: any): any; } ->z : ({ (x: number): number; (x: string): string; } | { (x: number): number; (x: any): any; })[] ->0 : number - -var r5 = r4(''); // any not string ->r5 : any ->r4('') : any ->r4 : { (x: number): number; (x: string): string; } | { (x: number): number; (x: any): any; } ->'' : string - -var r5b = r4(1); ->r5b : number ->r4(1) : number ->r4 : { (x: number): number; (x: string): string; } | { (x: number): number; (x: any): any; } ->1 : number - -var a2: { (x: T): number; (x: string): string;}; ->a2 : { (x: T): number; (x: string): string; } ->T : T ->x : T ->T : T ->x : string - -var b2: { (x: T): number; (x: string): string; }; ->b2 : { (x: T): number; (x: string): string; } ->T : T ->x : T ->T : T ->x : string - -var c2: { (x: number): number; (x: T): any; }; ->c2 : { (x: number): number; (x: T): any; } ->x : number ->T : T ->x : T ->T : T - -var z2 = [a2, b2, c2]; ->z2 : ({ (x: T): number; (x: string): string; } | { (x: number): number; (x: T): any; })[] ->[a2, b2, c2] : ({ (x: T): number; (x: string): string; } | { (x: number): number; (x: T): any; })[] ->a2 : { (x: T): number; (x: string): string; } ->b2 : { (x: T): number; (x: string): string; } ->c2 : { (x: number): number; (x: T): any; } - -var r6 = z2[0]; ->r6 : { (x: T): number; (x: string): string; } | { (x: number): number; (x: T): any; } ->z2[0] : { (x: T): number; (x: string): string; } | { (x: number): number; (x: T): any; } ->z2 : ({ (x: T): number; (x: string): string; } | { (x: number): number; (x: T): any; })[] ->0 : number - -var r7 = r6(''); // any not string ->r7 : any ->r6('') : any ->r6 : { (x: T): number; (x: string): string; } | { (x: number): number; (x: T): any; } ->'' : string - diff --git a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols index 3e23a7812f5..172336603ab 100644 --- a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols +++ b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.symbols @@ -82,7 +82,5 @@ var x4: IWithCallSignatures | IWithCallSignatures4 = a => /*here a should be any >IWithCallSignatures : Symbol(IWithCallSignatures, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 9, 1)) >IWithCallSignatures4 : Symbol(IWithCallSignatures4, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 18, 1)) >a : Symbol(a, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 35, 52)) ->a.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) >a : Symbol(a, Decl(contextualTypeWithUnionTypeCallSignatures.ts, 35, 52)) ->toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) diff --git a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types index 8e1915d4754..02dfecf5c08 100644 --- a/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types +++ b/tests/baselines/reference/contextualTypeWithUnionTypeCallSignatures.types @@ -90,10 +90,10 @@ var x4: IWithCallSignatures | IWithCallSignatures4 = a => /*here a should be any >x4 : IWithCallSignatures | IWithCallSignatures4 >IWithCallSignatures : IWithCallSignatures >IWithCallSignatures4 : IWithCallSignatures4 ->a => /*here a should be any*/ a.toString() : (a: number) => string ->a : number ->a.toString() : string ->a.toString : (radix?: number) => string ->a : number ->toString : (radix?: number) => string +>a => /*here a should be any*/ a.toString() : (a: any) => any +>a : any +>a.toString() : any +>a.toString : any +>a : any +>toString : any diff --git a/tests/baselines/reference/mismatchedExplicitTypeParameterAndArgumentType.errors.txt b/tests/baselines/reference/mismatchedExplicitTypeParameterAndArgumentType.errors.txt index 2fb7bd1bfbb..3711a386bf9 100644 --- a/tests/baselines/reference/mismatchedExplicitTypeParameterAndArgumentType.errors.txt +++ b/tests/baselines/reference/mismatchedExplicitTypeParameterAndArgumentType.errors.txt @@ -1,10 +1,11 @@ +tests/cases/compiler/mismatchedExplicitTypeParameterAndArgumentType.ts(7,30): error TS2349: Cannot invoke an expression whose type lacks a call signature. tests/cases/compiler/mismatchedExplicitTypeParameterAndArgumentType.ts(10,30): error TS2345: Argument of type '(string | number)[]' is not assignable to parameter of type 'number[]'. Type 'string | number' is not assignable to type 'number'. Type 'string' is not assignable to type 'number'. tests/cases/compiler/mismatchedExplicitTypeParameterAndArgumentType.ts(11,11): error TS2346: Supplied parameters do not match any signature of call target. -==== tests/cases/compiler/mismatchedExplicitTypeParameterAndArgumentType.ts (2 errors) ==== +==== tests/cases/compiler/mismatchedExplicitTypeParameterAndArgumentType.ts (3 errors) ==== function map(xs: T[], f: (x: T) => U) { var ys: U[] = []; xs.forEach(x => ys.push(f(x))); @@ -12,6 +13,8 @@ tests/cases/compiler/mismatchedExplicitTypeParameterAndArgumentType.ts(11,11): e } var r0 = map([1, ""], (x) => x.toString()); + ~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. var r5 = map([1, ""], (x) => x.toString()); var r6 = map([1, ""], (x) => x.toString()); var r7 = map([1, ""], (x) => x.toString()); // error diff --git a/tests/baselines/reference/typeGuardsInConditionalExpression.errors.txt b/tests/baselines/reference/typeGuardsInConditionalExpression.errors.txt new file mode 100644 index 00000000000..37a662e007c --- /dev/null +++ b/tests/baselines/reference/typeGuardsInConditionalExpression.errors.txt @@ -0,0 +1,103 @@ +tests/cases/conformance/expressions/typeGuards/typeGuardsInConditionalExpression.ts(93,22): error TS2349: Cannot invoke an expression whose type lacks a call signature. + + +==== tests/cases/conformance/expressions/typeGuards/typeGuardsInConditionalExpression.ts (1 errors) ==== + // In the true expression of a conditional expression, + // the type of a variable or parameter is narrowed by any type guard in the condition when true, + // provided the true expression contains no assignments to the variable or parameter. + // In the false expression of a conditional expression, + // the type of a variable or parameter is narrowed by any type guard in the condition when false, + // provided the false expression contains no assignments to the variable or parameter. + + function foo(x: number | string) { + return typeof x === "string" + ? x.length // string + : x++; // number + } + function foo2(x: number | string) { + // x is assigned in the if true branch, the type is not narrowed + return typeof x === "string" + ? (x = 10 && x)// string | number + : x; // string | number + } + function foo3(x: number | string) { + // x is assigned in the if false branch, the type is not narrowed + // even though assigned using same type as narrowed expression + return typeof x === "string" + ? (x = "Hello" && x) // string | number + : x; // string | number + } + function foo4(x: number | string) { + // false branch updates the variable - so here it is not number + // even though assigned using same type as narrowed expression + return typeof x === "string" + ? x // string | number + : (x = 10 && x); // string | number + } + function foo5(x: number | string) { + // false branch updates the variable - so here it is not number + return typeof x === "string" + ? x // string | number + : (x = "hello" && x); // string | number + } + function foo6(x: number | string) { + // Modify in both branches + return typeof x === "string" + ? (x = 10 && x) // string | number + : (x = "hello" && x); // string | number + } + function foo7(x: number | string | boolean) { + return typeof x === "string" + ? x === "hello" // string + : typeof x === "boolean" + ? x // boolean + : x == 10; // number + } + function foo8(x: number | string | boolean) { + var b: number | boolean; + return typeof x === "string" + ? x === "hello" + : ((b = x) && // number | boolean + (typeof x === "boolean" + ? x // boolean + : x == 10)); // number + } + function foo9(x: number | string) { + var y = 10; + // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop + return typeof x === "string" + ? ((y = x.length) && x === "hello") // string + : x === 10; // number + } + function foo10(x: number | string | boolean) { + // Mixing typeguards + var b: boolean | number; + return typeof x === "string" + ? x // string + : ((b = x) // x is number | boolean + && typeof x === "number" + && x.toString()); // x is number + } + function foo11(x: number | string | boolean) { + // Mixing typeguards + // Assigning value to x deep inside another guard stops narrowing of type too + var b: number | boolean | string; + return typeof x === "string" + ? x // number | boolean | string - changed in the false branch + : ((b = x) // x is number | boolean | string - because the assignment changed it + && typeof x === "number" + && (x = 10) // assignment to x + && x); // x is number | boolean | string + } + function foo12(x: number | string | boolean) { + // Mixing typeguards + // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression + var b: number | boolean | string; + return typeof x === "string" + ? (x = 10 && x.toString().length) // number | boolean | string - changed here + ~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + : ((b = x) // x is number | boolean | string - changed in true branch + && typeof x === "number" + && x); // x is number + } \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardsInConditionalExpression.symbols b/tests/baselines/reference/typeGuardsInConditionalExpression.symbols deleted file mode 100644 index 2a7eb47523f..00000000000 --- a/tests/baselines/reference/typeGuardsInConditionalExpression.symbols +++ /dev/null @@ -1,251 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsInConditionalExpression.ts === -// In the true expression of a conditional expression, -// the type of a variable or parameter is narrowed by any type guard in the condition when true, -// provided the true expression contains no assignments to the variable or parameter. -// In the false expression of a conditional expression, -// the type of a variable or parameter is narrowed by any type guard in the condition when false, -// provided the false expression contains no assignments to the variable or parameter. - -function foo(x: number | string) { ->foo : Symbol(foo, Decl(typeGuardsInConditionalExpression.ts, 0, 0)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 7, 13)) - - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 7, 13)) - - ? x.length // string ->x.length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 7, 13)) ->length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) - - : x++; // number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 7, 13)) -} -function foo2(x: number | string) { ->foo2 : Symbol(foo2, Decl(typeGuardsInConditionalExpression.ts, 11, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 12, 14)) - - // x is assigned in the if true branch, the type is not narrowed - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 12, 14)) - - ? (x = 10 && x)// string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 12, 14)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 12, 14)) - - : x; // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 12, 14)) -} -function foo3(x: number | string) { ->foo3 : Symbol(foo3, Decl(typeGuardsInConditionalExpression.ts, 17, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 18, 14)) - - // x is assigned in the if false branch, the type is not narrowed - // even though assigned using same type as narrowed expression - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 18, 14)) - - ? (x = "Hello" && x) // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 18, 14)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 18, 14)) - - : x; // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 18, 14)) -} -function foo4(x: number | string) { ->foo4 : Symbol(foo4, Decl(typeGuardsInConditionalExpression.ts, 24, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 25, 14)) - - // false branch updates the variable - so here it is not number - // even though assigned using same type as narrowed expression - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 25, 14)) - - ? x // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 25, 14)) - - : (x = 10 && x); // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 25, 14)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 25, 14)) -} -function foo5(x: number | string) { ->foo5 : Symbol(foo5, Decl(typeGuardsInConditionalExpression.ts, 31, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) - - // false branch updates the variable - so here it is not number - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) - - ? x // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) - - : (x = "hello" && x); // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 32, 14)) -} -function foo6(x: number | string) { ->foo6 : Symbol(foo6, Decl(typeGuardsInConditionalExpression.ts, 37, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) - - // Modify in both branches - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) - - ? (x = 10 && x) // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) - - : (x = "hello" && x); // string | number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 38, 14)) -} -function foo7(x: number | string | boolean) { ->foo7 : Symbol(foo7, Decl(typeGuardsInConditionalExpression.ts, 43, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) - - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) - - ? x === "hello" // string ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) - - : typeof x === "boolean" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) - - ? x // boolean ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) - - : x == 10; // number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 44, 14)) -} -function foo8(x: number | string | boolean) { ->foo8 : Symbol(foo8, Decl(typeGuardsInConditionalExpression.ts, 50, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) - - var b: number | boolean; ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 52, 7)) - - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) - - ? x === "hello" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) - - : ((b = x) && // number | boolean ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 52, 7)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) - - (typeof x === "boolean" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) - - ? x // boolean ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) - - : x == 10)); // number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 51, 14)) -} -function foo9(x: number | string) { ->foo9 : Symbol(foo9, Decl(typeGuardsInConditionalExpression.ts, 59, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 60, 14)) - - var y = 10; ->y : Symbol(y, Decl(typeGuardsInConditionalExpression.ts, 61, 7)) - - // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 60, 14)) - - ? ((y = x.length) && x === "hello") // string ->y : Symbol(y, Decl(typeGuardsInConditionalExpression.ts, 61, 7)) ->x.length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 60, 14)) ->length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 60, 14)) - - : x === 10; // number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 60, 14)) -} -function foo10(x: number | string | boolean) { ->foo10 : Symbol(foo10, Decl(typeGuardsInConditionalExpression.ts, 66, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) - - // Mixing typeguards - var b: boolean | number; ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 69, 7)) - - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) - - ? x // string ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) - - : ((b = x) // x is number | boolean ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 69, 7)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) - - && typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) - - && x.toString()); // x is number ->x.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 67, 15)) ->toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) -} -function foo11(x: number | string | boolean) { ->foo11 : Symbol(foo11, Decl(typeGuardsInConditionalExpression.ts, 75, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) - - // Mixing typeguards - // Assigning value to x deep inside another guard stops narrowing of type too - var b: number | boolean | string; ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 79, 7)) - - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) - - ? x // number | boolean | string - changed in the false branch ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) - - : ((b = x) // x is number | boolean | string - because the assignment changed it ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 79, 7)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) - - && typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) - - && (x = 10) // assignment to x ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) - - && x); // x is number | boolean | string ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 76, 15)) -} -function foo12(x: number | string | boolean) { ->foo12 : Symbol(foo12, Decl(typeGuardsInConditionalExpression.ts, 86, 1)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) - - // Mixing typeguards - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - var b: number | boolean | string; ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 90, 7)) - - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) - - ? (x = 10 && x.toString().length) // number | boolean | string - changed here ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) ->x.toString().length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) ->x.toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) ->toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) ->length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) - - : ((b = x) // x is number | boolean | string - changed in true branch ->b : Symbol(b, Decl(typeGuardsInConditionalExpression.ts, 90, 7)) ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) - - && typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) - - && x); // x is number ->x : Symbol(x, Decl(typeGuardsInConditionalExpression.ts, 87, 15)) -} diff --git a/tests/baselines/reference/typeGuardsInConditionalExpression.types b/tests/baselines/reference/typeGuardsInConditionalExpression.types deleted file mode 100644 index 1518b605af7..00000000000 --- a/tests/baselines/reference/typeGuardsInConditionalExpression.types +++ /dev/null @@ -1,388 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsInConditionalExpression.ts === -// In the true expression of a conditional expression, -// the type of a variable or parameter is narrowed by any type guard in the condition when true, -// provided the true expression contains no assignments to the variable or parameter. -// In the false expression of a conditional expression, -// the type of a variable or parameter is narrowed by any type guard in the condition when false, -// provided the false expression contains no assignments to the variable or parameter. - -function foo(x: number | string) { ->foo : (x: string | number) => number ->x : string | number - - return typeof x === "string" ->typeof x === "string" ? x.length // string : x++ : number ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - ? x.length // string ->x.length : number ->x : string ->length : number - - : x++; // number ->x++ : number ->x : number -} -function foo2(x: number | string) { ->foo2 : (x: string | number) => string | number ->x : string | number - - // x is assigned in the if true branch, the type is not narrowed - return typeof x === "string" ->typeof x === "string" ? (x = 10 && x)// string | number : x : string | number ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - ? (x = 10 && x)// string | number ->(x = 10 && x) : string | number ->x = 10 && x : string | number ->x : string | number ->10 && x : string | number ->10 : number ->x : string | number - - : x; // string | number ->x : string | number -} -function foo3(x: number | string) { ->foo3 : (x: string | number) => string | number ->x : string | number - - // x is assigned in the if false branch, the type is not narrowed - // even though assigned using same type as narrowed expression - return typeof x === "string" ->typeof x === "string" ? (x = "Hello" && x) // string | number : x : string | number ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - ? (x = "Hello" && x) // string | number ->(x = "Hello" && x) : string | number ->x = "Hello" && x : string | number ->x : string | number ->"Hello" && x : string | number ->"Hello" : string ->x : string | number - - : x; // string | number ->x : string | number -} -function foo4(x: number | string) { ->foo4 : (x: string | number) => string | number ->x : string | number - - // false branch updates the variable - so here it is not number - // even though assigned using same type as narrowed expression - return typeof x === "string" ->typeof x === "string" ? x // string | number : (x = 10 && x) : string | number ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - ? x // string | number ->x : string | number - - : (x = 10 && x); // string | number ->(x = 10 && x) : string | number ->x = 10 && x : string | number ->x : string | number ->10 && x : string | number ->10 : number ->x : string | number -} -function foo5(x: number | string) { ->foo5 : (x: string | number) => string | number ->x : string | number - - // false branch updates the variable - so here it is not number - return typeof x === "string" ->typeof x === "string" ? x // string | number : (x = "hello" && x) : string | number ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - ? x // string | number ->x : string | number - - : (x = "hello" && x); // string | number ->(x = "hello" && x) : string | number ->x = "hello" && x : string | number ->x : string | number ->"hello" && x : string | number ->"hello" : string ->x : string | number -} -function foo6(x: number | string) { ->foo6 : (x: string | number) => string | number ->x : string | number - - // Modify in both branches - return typeof x === "string" ->typeof x === "string" ? (x = 10 && x) // string | number : (x = "hello" && x) : string | number ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - ? (x = 10 && x) // string | number ->(x = 10 && x) : string | number ->x = 10 && x : string | number ->x : string | number ->10 && x : string | number ->10 : number ->x : string | number - - : (x = "hello" && x); // string | number ->(x = "hello" && x) : string | number ->x = "hello" && x : string | number ->x : string | number ->"hello" && x : string | number ->"hello" : string ->x : string | number -} -function foo7(x: number | string | boolean) { ->foo7 : (x: string | number | boolean) => boolean ->x : string | number | boolean - - return typeof x === "string" ->typeof x === "string" ? x === "hello" // string : typeof x === "boolean" ? x // boolean : x == 10 : boolean ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - ? x === "hello" // string ->x === "hello" : boolean ->x : string ->"hello" : string - - : typeof x === "boolean" ->typeof x === "boolean" ? x // boolean : x == 10 : boolean ->typeof x === "boolean" : boolean ->typeof x : string ->x : number | boolean ->"boolean" : string - - ? x // boolean ->x : boolean - - : x == 10; // number ->x == 10 : boolean ->x : number ->10 : number -} -function foo8(x: number | string | boolean) { ->foo8 : (x: string | number | boolean) => boolean ->x : string | number | boolean - - var b: number | boolean; ->b : number | boolean - - return typeof x === "string" ->typeof x === "string" ? x === "hello" : ((b = x) && // number | boolean (typeof x === "boolean" ? x // boolean : x == 10)) : boolean ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - ? x === "hello" ->x === "hello" : boolean ->x : string ->"hello" : string - - : ((b = x) && // number | boolean ->((b = x) && // number | boolean (typeof x === "boolean" ? x // boolean : x == 10)) : boolean ->(b = x) && // number | boolean (typeof x === "boolean" ? x // boolean : x == 10) : boolean ->(b = x) : number | boolean ->b = x : number | boolean ->b : number | boolean ->x : number | boolean - - (typeof x === "boolean" ->(typeof x === "boolean" ? x // boolean : x == 10) : boolean ->typeof x === "boolean" ? x // boolean : x == 10 : boolean ->typeof x === "boolean" : boolean ->typeof x : string ->x : number | boolean ->"boolean" : string - - ? x // boolean ->x : boolean - - : x == 10)); // number ->x == 10 : boolean ->x : number ->10 : number -} -function foo9(x: number | string) { ->foo9 : (x: string | number) => boolean ->x : string | number - - var y = 10; ->y : number ->10 : number - - // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop - return typeof x === "string" ->typeof x === "string" ? ((y = x.length) && x === "hello") // string : x === 10 : boolean ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - ? ((y = x.length) && x === "hello") // string ->((y = x.length) && x === "hello") : boolean ->(y = x.length) && x === "hello" : boolean ->(y = x.length) : number ->y = x.length : number ->y : number ->x.length : number ->x : string ->length : number ->x === "hello" : boolean ->x : string ->"hello" : string - - : x === 10; // number ->x === 10 : boolean ->x : number ->10 : number -} -function foo10(x: number | string | boolean) { ->foo10 : (x: string | number | boolean) => string ->x : string | number | boolean - - // Mixing typeguards - var b: boolean | number; ->b : number | boolean - - return typeof x === "string" ->typeof x === "string" ? x // string : ((b = x) // x is number | boolean && typeof x === "number" && x.toString()) : string ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - ? x // string ->x : string - - : ((b = x) // x is number | boolean ->((b = x) // x is number | boolean && typeof x === "number" && x.toString()) : string ->(b = x) // x is number | boolean && typeof x === "number" && x.toString() : string ->(b = x) // x is number | boolean && typeof x === "number" : boolean ->(b = x) : number | boolean ->b = x : number | boolean ->b : number | boolean ->x : number | boolean - - && typeof x === "number" ->typeof x === "number" : boolean ->typeof x : string ->x : number | boolean ->"number" : string - - && x.toString()); // x is number ->x.toString() : string ->x.toString : (radix?: number) => string ->x : number ->toString : (radix?: number) => string -} -function foo11(x: number | string | boolean) { ->foo11 : (x: string | number | boolean) => string | number | boolean ->x : string | number | boolean - - // Mixing typeguards - // Assigning value to x deep inside another guard stops narrowing of type too - var b: number | boolean | string; ->b : string | number | boolean - - return typeof x === "string" ->typeof x === "string" ? x // number | boolean | string - changed in the false branch : ((b = x) // x is number | boolean | string - because the assignment changed it && typeof x === "number" && (x = 10) // assignment to x && x) : string | number | boolean ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - ? x // number | boolean | string - changed in the false branch ->x : string | number | boolean - - : ((b = x) // x is number | boolean | string - because the assignment changed it ->((b = x) // x is number | boolean | string - because the assignment changed it && typeof x === "number" && (x = 10) // assignment to x && x) : string | number | boolean ->(b = x) // x is number | boolean | string - because the assignment changed it && typeof x === "number" && (x = 10) // assignment to x && x : string | number | boolean ->(b = x) // x is number | boolean | string - because the assignment changed it && typeof x === "number" && (x = 10) : number ->(b = x) // x is number | boolean | string - because the assignment changed it && typeof x === "number" : boolean ->(b = x) : string | number | boolean ->b = x : string | number | boolean ->b : string | number | boolean ->x : string | number | boolean - - && typeof x === "number" ->typeof x === "number" : boolean ->typeof x : string ->x : string | number | boolean ->"number" : string - - && (x = 10) // assignment to x ->(x = 10) : number ->x = 10 : number ->x : string | number | boolean ->10 : number - - && x); // x is number | boolean | string ->x : string | number | boolean -} -function foo12(x: number | string | boolean) { ->foo12 : (x: string | number | boolean) => number ->x : string | number | boolean - - // Mixing typeguards - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - var b: number | boolean | string; ->b : string | number | boolean - - return typeof x === "string" ->typeof x === "string" ? (x = 10 && x.toString().length) // number | boolean | string - changed here : ((b = x) // x is number | boolean | string - changed in true branch && typeof x === "number" && x) : number ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - ? (x = 10 && x.toString().length) // number | boolean | string - changed here ->(x = 10 && x.toString().length) : number ->x = 10 && x.toString().length : number ->x : string | number | boolean ->10 && x.toString().length : number ->10 : number ->x.toString().length : number ->x.toString() : string ->x.toString : ((radix?: number) => string) | (() => string) ->x : string | number | boolean ->toString : ((radix?: number) => string) | (() => string) ->length : number - - : ((b = x) // x is number | boolean | string - changed in true branch ->((b = x) // x is number | boolean | string - changed in true branch && typeof x === "number" && x) : number ->(b = x) // x is number | boolean | string - changed in true branch && typeof x === "number" && x : number ->(b = x) // x is number | boolean | string - changed in true branch && typeof x === "number" : boolean ->(b = x) : string | number | boolean ->b = x : string | number | boolean ->b : string | number | boolean ->x : string | number | boolean - - && typeof x === "number" ->typeof x === "number" : boolean ->typeof x : string ->x : string | number | boolean ->"number" : string - - && x); // x is number ->x : number -} diff --git a/tests/baselines/reference/typeGuardsInIfStatement.errors.txt b/tests/baselines/reference/typeGuardsInIfStatement.errors.txt new file mode 100644 index 00000000000..e675daffd6e --- /dev/null +++ b/tests/baselines/reference/typeGuardsInIfStatement.errors.txt @@ -0,0 +1,160 @@ +tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts(127,23): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts(131,22): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts(139,16): error TS2349: Cannot invoke an expression whose type lacks a call signature. + + +==== tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts (3 errors) ==== + // In the true branch statement of an �if� statement, + // the type of a variable or parameter is narrowed by any type guard in the �if� condition when true, + // provided the true branch statement contains no assignments to the variable or parameter. + // In the false branch statement of an �if� statement, + // the type of a variable or parameter is narrowed by any type guard in the �if� condition when false, + // provided the false branch statement contains no assignments to the variable or parameter + function foo(x: number | string) { + if (typeof x === "string") { + return x.length; // string + } + else { + return x++; // number + } + } + function foo2(x: number | string) { + // x is assigned in the if true branch, the type is not narrowed + if (typeof x === "string") { + x = 10; + return x; // string | number + } + else { + return x; // string | number + } + } + function foo3(x: number | string) { + // x is assigned in the if true branch, the type is not narrowed + if (typeof x === "string") { + x = "Hello"; // even though assigned using same type as narrowed expression + return x; // string | number + } + else { + return x; // string | number + } + } + function foo4(x: number | string) { + // false branch updates the variable - so here it is not number + if (typeof x === "string") { + return x; // string | number + } + else { + x = 10; // even though assigned number - this should result in x to be string | number + return x; // string | number + } + } + function foo5(x: number | string) { + // false branch updates the variable - so here it is not number + if (typeof x === "string") { + return x; // string | number + } + else { + x = "hello"; + return x; // string | number + } + } + function foo6(x: number | string) { + // Modify in both branches + if (typeof x === "string") { + x = 10; + return x; // string | number + } + else { + x = "hello"; + return x; // string | number + } + } + function foo7(x: number | string | boolean) { + if (typeof x === "string") { + return x === "hello"; // string + } + else if (typeof x === "boolean") { + return x; // boolean + } + else { + return x == 10; // number + } + } + function foo8(x: number | string | boolean) { + if (typeof x === "string") { + return x === "hello"; // string + } + else { + var b: number | boolean = x; // number | boolean + if (typeof x === "boolean") { + return x; // boolean + } + else { + return x == 10; // number + } + } + } + function foo9(x: number | string) { + var y = 10; + if (typeof x === "string") { + // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop + y = x.length; + return x === "hello"; // string + } + else { + return x == 10; // number + } + } + function foo10(x: number | string | boolean) { + // Mixing typeguard narrowing in if statement with conditional expression typeguard + if (typeof x === "string") { + return x === "hello"; // string + } + else { + var y: boolean | string; + var b = x; // number | boolean + return typeof x === "number" + ? x === 10 // number + : x; // x should be boolean + } + } + function foo11(x: number | string | boolean) { + // Mixing typeguard narrowing in if statement with conditional expression typeguard + // Assigning value to x deep inside another guard stops narrowing of type too + if (typeof x === "string") { + return x; // string | number | boolean - x changed in else branch + } + else { + var y: number| boolean | string; + var b = x; // number | boolean | string - because below we are changing value of x in if statement + return typeof x === "number" + ? ( + // change value of x + x = 10 && x.toString() // number | boolean | string + ~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + ) + : ( + // do not change value + y = x && x.toString() // number | boolean | string + ~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + ); + } + } + function foo12(x: number | string | boolean) { + // Mixing typeguard narrowing in if statement with conditional expression typeguard + // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression + if (typeof x === "string") { + return x.toString(); // string | number | boolean - x changed in else branch + ~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + } + else { + x = 10; + var b = x; // number | boolean | string + return typeof x === "number" + ? x.toString() // number + : x.toString(); // boolean | string + } + } \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardsInIfStatement.symbols b/tests/baselines/reference/typeGuardsInIfStatement.symbols deleted file mode 100644 index d81be08d1a0..00000000000 --- a/tests/baselines/reference/typeGuardsInIfStatement.symbols +++ /dev/null @@ -1,304 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts === -// In the true branch statement of an �if� statement, -// the type of a variable or parameter is narrowed by any type guard in the �if� condition when true, -// provided the true branch statement contains no assignments to the variable or parameter. -// In the false branch statement of an �if� statement, -// the type of a variable or parameter is narrowed by any type guard in the �if� condition when false, -// provided the false branch statement contains no assignments to the variable or parameter -function foo(x: number | string) { ->foo : Symbol(foo, Decl(typeGuardsInIfStatement.ts, 0, 0)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 6, 13)) - - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 6, 13)) - - return x.length; // string ->x.length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 6, 13)) ->length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) - } - else { - return x++; // number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 6, 13)) - } -} -function foo2(x: number | string) { ->foo2 : Symbol(foo2, Decl(typeGuardsInIfStatement.ts, 13, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 14, 14)) - - // x is assigned in the if true branch, the type is not narrowed - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 14, 14)) - - x = 10; ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 14, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 14, 14)) - } - else { - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 14, 14)) - } -} -function foo3(x: number | string) { ->foo3 : Symbol(foo3, Decl(typeGuardsInIfStatement.ts, 23, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 24, 14)) - - // x is assigned in the if true branch, the type is not narrowed - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 24, 14)) - - x = "Hello"; // even though assigned using same type as narrowed expression ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 24, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 24, 14)) - } - else { - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 24, 14)) - } -} -function foo4(x: number | string) { ->foo4 : Symbol(foo4, Decl(typeGuardsInIfStatement.ts, 33, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 34, 14)) - - // false branch updates the variable - so here it is not number - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 34, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 34, 14)) - } - else { - x = 10; // even though assigned number - this should result in x to be string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 34, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 34, 14)) - } -} -function foo5(x: number | string) { ->foo5 : Symbol(foo5, Decl(typeGuardsInIfStatement.ts, 43, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 44, 14)) - - // false branch updates the variable - so here it is not number - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 44, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 44, 14)) - } - else { - x = "hello"; ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 44, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 44, 14)) - } -} -function foo6(x: number | string) { ->foo6 : Symbol(foo6, Decl(typeGuardsInIfStatement.ts, 53, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - - // Modify in both branches - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - - x = 10; ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - } - else { - x = "hello"; ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - - return x; // string | number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 54, 14)) - } -} -function foo7(x: number | string | boolean) { ->foo7 : Symbol(foo7, Decl(typeGuardsInIfStatement.ts, 64, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - - return x === "hello"; // string ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - } - else if (typeof x === "boolean") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - - return x; // boolean ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - } - else { - return x == 10; // number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 65, 14)) - } -} -function foo8(x: number | string | boolean) { ->foo8 : Symbol(foo8, Decl(typeGuardsInIfStatement.ts, 75, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - - return x === "hello"; // string ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - } - else { - var b: number | boolean = x; // number | boolean ->b : Symbol(b, Decl(typeGuardsInIfStatement.ts, 81, 11)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - - if (typeof x === "boolean") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - - return x; // boolean ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - } - else { - return x == 10; // number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 76, 14)) - } - } -} -function foo9(x: number | string) { ->foo9 : Symbol(foo9, Decl(typeGuardsInIfStatement.ts, 89, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 90, 14)) - - var y = 10; ->y : Symbol(y, Decl(typeGuardsInIfStatement.ts, 91, 7)) - - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 90, 14)) - - // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop - y = x.length; ->y : Symbol(y, Decl(typeGuardsInIfStatement.ts, 91, 7)) ->x.length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 90, 14)) ->length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) - - return x === "hello"; // string ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 90, 14)) - } - else { - return x == 10; // number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 90, 14)) - } -} -function foo10(x: number | string | boolean) { ->foo10 : Symbol(foo10, Decl(typeGuardsInIfStatement.ts, 100, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - - return x === "hello"; // string ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - } - else { - var y: boolean | string; ->y : Symbol(y, Decl(typeGuardsInIfStatement.ts, 107, 11)) - - var b = x; // number | boolean ->b : Symbol(b, Decl(typeGuardsInIfStatement.ts, 108, 11)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - - return typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - - ? x === 10 // number ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - - : x; // x should be boolean ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 101, 15)) - } -} -function foo11(x: number | string | boolean) { ->foo11 : Symbol(foo11, Decl(typeGuardsInIfStatement.ts, 113, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - // Assigning value to x deep inside another guard stops narrowing of type too - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) - - return x; // string | number | boolean - x changed in else branch ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) - } - else { - var y: number| boolean | string; ->y : Symbol(y, Decl(typeGuardsInIfStatement.ts, 121, 11)) - - var b = x; // number | boolean | string - because below we are changing value of x in if statement ->b : Symbol(b, Decl(typeGuardsInIfStatement.ts, 122, 11)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) - - return typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) - - ? ( - // change value of x - x = 10 && x.toString() // number | boolean | string ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) ->x.toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) ->toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) - - ) - : ( - // do not change value - y = x && x.toString() // number | boolean | string ->y : Symbol(y, Decl(typeGuardsInIfStatement.ts, 121, 11)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) ->x.toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 114, 15)) ->toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) - - ); - } -} -function foo12(x: number | string | boolean) { ->foo12 : Symbol(foo12, Decl(typeGuardsInIfStatement.ts, 133, 1)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - if (typeof x === "string") { ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) - - return x.toString(); // string | number | boolean - x changed in else branch ->x.toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) ->toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) - } - else { - x = 10; ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) - - var b = x; // number | boolean | string ->b : Symbol(b, Decl(typeGuardsInIfStatement.ts, 142, 11)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) - - return typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) - - ? x.toString() // number ->x.toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) ->toString : Symbol(Number.toString, Decl(lib.d.ts, 458, 18)) - - : x.toString(); // boolean | string ->x.toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 96, 26)) ->x : Symbol(x, Decl(typeGuardsInIfStatement.ts, 134, 15)) ->toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 96, 26)) - } -} diff --git a/tests/baselines/reference/typeGuardsInIfStatement.types b/tests/baselines/reference/typeGuardsInIfStatement.types deleted file mode 100644 index e682c3da895..00000000000 --- a/tests/baselines/reference/typeGuardsInIfStatement.types +++ /dev/null @@ -1,405 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts === -// In the true branch statement of an �if� statement, -// the type of a variable or parameter is narrowed by any type guard in the �if� condition when true, -// provided the true branch statement contains no assignments to the variable or parameter. -// In the false branch statement of an �if� statement, -// the type of a variable or parameter is narrowed by any type guard in the �if� condition when false, -// provided the false branch statement contains no assignments to the variable or parameter -function foo(x: number | string) { ->foo : (x: string | number) => number ->x : string | number - - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - return x.length; // string ->x.length : number ->x : string ->length : number - } - else { - return x++; // number ->x++ : number ->x : number - } -} -function foo2(x: number | string) { ->foo2 : (x: string | number) => string | number ->x : string | number - - // x is assigned in the if true branch, the type is not narrowed - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - x = 10; ->x = 10 : number ->x : string | number ->10 : number - - return x; // string | number ->x : string | number - } - else { - return x; // string | number ->x : string | number - } -} -function foo3(x: number | string) { ->foo3 : (x: string | number) => string | number ->x : string | number - - // x is assigned in the if true branch, the type is not narrowed - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - x = "Hello"; // even though assigned using same type as narrowed expression ->x = "Hello" : string ->x : string | number ->"Hello" : string - - return x; // string | number ->x : string | number - } - else { - return x; // string | number ->x : string | number - } -} -function foo4(x: number | string) { ->foo4 : (x: string | number) => string | number ->x : string | number - - // false branch updates the variable - so here it is not number - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - return x; // string | number ->x : string | number - } - else { - x = 10; // even though assigned number - this should result in x to be string | number ->x = 10 : number ->x : string | number ->10 : number - - return x; // string | number ->x : string | number - } -} -function foo5(x: number | string) { ->foo5 : (x: string | number) => string | number ->x : string | number - - // false branch updates the variable - so here it is not number - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - return x; // string | number ->x : string | number - } - else { - x = "hello"; ->x = "hello" : string ->x : string | number ->"hello" : string - - return x; // string | number ->x : string | number - } -} -function foo6(x: number | string) { ->foo6 : (x: string | number) => string | number ->x : string | number - - // Modify in both branches - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - x = 10; ->x = 10 : number ->x : string | number ->10 : number - - return x; // string | number ->x : string | number - } - else { - x = "hello"; ->x = "hello" : string ->x : string | number ->"hello" : string - - return x; // string | number ->x : string | number - } -} -function foo7(x: number | string | boolean) { ->foo7 : (x: string | number | boolean) => boolean ->x : string | number | boolean - - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - return x === "hello"; // string ->x === "hello" : boolean ->x : string ->"hello" : string - } - else if (typeof x === "boolean") { ->typeof x === "boolean" : boolean ->typeof x : string ->x : number | boolean ->"boolean" : string - - return x; // boolean ->x : boolean - } - else { - return x == 10; // number ->x == 10 : boolean ->x : number ->10 : number - } -} -function foo8(x: number | string | boolean) { ->foo8 : (x: string | number | boolean) => boolean ->x : string | number | boolean - - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - return x === "hello"; // string ->x === "hello" : boolean ->x : string ->"hello" : string - } - else { - var b: number | boolean = x; // number | boolean ->b : number | boolean ->x : number | boolean - - if (typeof x === "boolean") { ->typeof x === "boolean" : boolean ->typeof x : string ->x : number | boolean ->"boolean" : string - - return x; // boolean ->x : boolean - } - else { - return x == 10; // number ->x == 10 : boolean ->x : number ->10 : number - } - } -} -function foo9(x: number | string) { ->foo9 : (x: string | number) => boolean ->x : string | number - - var y = 10; ->y : number ->10 : number - - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop - y = x.length; ->y = x.length : number ->y : number ->x.length : number ->x : string ->length : number - - return x === "hello"; // string ->x === "hello" : boolean ->x : string ->"hello" : string - } - else { - return x == 10; // number ->x == 10 : boolean ->x : number ->10 : number - } -} -function foo10(x: number | string | boolean) { ->foo10 : (x: string | number | boolean) => boolean ->x : string | number | boolean - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - return x === "hello"; // string ->x === "hello" : boolean ->x : string ->"hello" : string - } - else { - var y: boolean | string; ->y : string | boolean - - var b = x; // number | boolean ->b : number | boolean ->x : number | boolean - - return typeof x === "number" ->typeof x === "number" ? x === 10 // number : x : boolean ->typeof x === "number" : boolean ->typeof x : string ->x : number | boolean ->"number" : string - - ? x === 10 // number ->x === 10 : boolean ->x : number ->10 : number - - : x; // x should be boolean ->x : boolean - } -} -function foo11(x: number | string | boolean) { ->foo11 : (x: string | number | boolean) => string | number | boolean ->x : string | number | boolean - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - // Assigning value to x deep inside another guard stops narrowing of type too - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - return x; // string | number | boolean - x changed in else branch ->x : string | number | boolean - } - else { - var y: number| boolean | string; ->y : string | number | boolean - - var b = x; // number | boolean | string - because below we are changing value of x in if statement ->b : string | number | boolean ->x : string | number | boolean - - return typeof x === "number" ->typeof x === "number" ? ( // change value of x x = 10 && x.toString() // number | boolean | string ) : ( // do not change value y = x && x.toString() // number | boolean | string ) : string ->typeof x === "number" : boolean ->typeof x : string ->x : string | number | boolean ->"number" : string - - ? ( ->( // change value of x x = 10 && x.toString() // number | boolean | string ) : string - - // change value of x - x = 10 && x.toString() // number | boolean | string ->x = 10 && x.toString() : string ->x : string | number | boolean ->10 && x.toString() : string ->10 : number ->x.toString() : string ->x.toString : (() => string) | ((radix?: number) => string) ->x : string | number | boolean ->toString : (() => string) | ((radix?: number) => string) - - ) - : ( ->( // do not change value y = x && x.toString() // number | boolean | string ) : string - - // do not change value - y = x && x.toString() // number | boolean | string ->y = x && x.toString() : string ->y : string | number | boolean ->x && x.toString() : string ->x : string | number | boolean ->x.toString() : string ->x.toString : (() => string) | ((radix?: number) => string) ->x : string | number | boolean ->toString : (() => string) | ((radix?: number) => string) - - ); - } -} -function foo12(x: number | string | boolean) { ->foo12 : (x: string | number | boolean) => string ->x : string | number | boolean - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - if (typeof x === "string") { ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - return x.toString(); // string | number | boolean - x changed in else branch ->x.toString() : string ->x.toString : (() => string) | ((radix?: number) => string) ->x : string | number | boolean ->toString : (() => string) | ((radix?: number) => string) - } - else { - x = 10; ->x = 10 : number ->x : string | number | boolean ->10 : number - - var b = x; // number | boolean | string ->b : string | number | boolean ->x : string | number | boolean - - return typeof x === "number" ->typeof x === "number" ? x.toString() // number : x.toString() : string ->typeof x === "number" : boolean ->typeof x : string ->x : string | number | boolean ->"number" : string - - ? x.toString() // number ->x.toString() : string ->x.toString : (radix?: number) => string ->x : number ->toString : (radix?: number) => string - - : x.toString(); // boolean | string ->x.toString() : string ->x.toString : () => string ->x : string | boolean ->toString : () => string - } -} diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.errors.txt b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.errors.txt new file mode 100644 index 00000000000..f44e433a2c8 --- /dev/null +++ b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.errors.txt @@ -0,0 +1,64 @@ +tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts(43,22): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts(45,21): error TS2349: Cannot invoke an expression whose type lacks a call signature. + + +==== tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts (2 errors) ==== + // In the right operand of a && operation, + // the type of a variable or parameter is narrowed by any type guard in the left operand when true, + // provided the right operand contains no assignments to the variable or parameter. + function foo(x: number | string) { + return typeof x === "string" && x.length === 10; // string + } + function foo2(x: number | string) { + // modify x in right hand operand + return typeof x === "string" && ((x = 10) && x); // string | number + } + function foo3(x: number | string) { + // modify x in right hand operand with string type itself + return typeof x === "string" && ((x = "hello") && x); // string | number + } + function foo4(x: number | string | boolean) { + return typeof x !== "string" // string | number | boolean + && typeof x !== "number" // number | boolean + && x; // boolean + } + function foo5(x: number | string | boolean) { + // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop + var b: number | boolean; + return typeof x !== "string" // string | number | boolean + && ((b = x) && (typeof x !== "number" // number | boolean + && x)); // boolean + } + function foo6(x: number | string | boolean) { + // Mixing typeguard narrowing in if statement with conditional expression typeguard + return typeof x !== "string" // string | number | boolean + && (typeof x !== "number" // number | boolean + ? x // boolean + : x === 10) // number + } + function foo7(x: number | string | boolean) { + var y: number| boolean | string; + var z: number| boolean | string; + // Mixing typeguard narrowing + // Assigning value to x deep inside another guard stops narrowing of type too + return typeof x !== "string" + && ((z = x) // string | number | boolean - x changed deeper in conditional expression + && (typeof x === "number" + // change value of x + ? (x = 10 && x.toString()) // number | boolean | string + ~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + // do not change value + : (y = x && x.toString()))); // number | boolean | string + ~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + } + function foo8(x: number | string) { + // Mixing typeguard + // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression + return typeof x !== "string" + && (x = 10) // change x - number| string + && (typeof x === "number" + ? x // number + : x.length); // string + } \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.symbols b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.symbols deleted file mode 100644 index 2a757460234..00000000000 --- a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.symbols +++ /dev/null @@ -1,143 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts === -// In the right operand of a && operation, -// the type of a variable or parameter is narrowed by any type guard in the left operand when true, -// provided the right operand contains no assignments to the variable or parameter. -function foo(x: number | string) { ->foo : Symbol(foo, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 0, 0)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 3, 13)) - - return typeof x === "string" && x.length === 10; // string ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 3, 13)) ->x.length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 3, 13)) ->length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) -} -function foo2(x: number | string) { ->foo2 : Symbol(foo2, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 5, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 6, 14)) - - // modify x in right hand operand - return typeof x === "string" && ((x = 10) && x); // string | number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 6, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 6, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 6, 14)) -} -function foo3(x: number | string) { ->foo3 : Symbol(foo3, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 9, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 10, 14)) - - // modify x in right hand operand with string type itself - return typeof x === "string" && ((x = "hello") && x); // string | number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 10, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 10, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 10, 14)) -} -function foo4(x: number | string | boolean) { ->foo4 : Symbol(foo4, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 13, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 14, 14)) - - return typeof x !== "string" // string | number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 14, 14)) - - && typeof x !== "number" // number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 14, 14)) - - && x; // boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 14, 14)) -} -function foo5(x: number | string | boolean) { ->foo5 : Symbol(foo5, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 18, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 19, 14)) - - // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop - var b: number | boolean; ->b : Symbol(b, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 21, 7)) - - return typeof x !== "string" // string | number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 19, 14)) - - && ((b = x) && (typeof x !== "number" // number | boolean ->b : Symbol(b, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 21, 7)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 19, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 19, 14)) - - && x)); // boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 19, 14)) -} -function foo6(x: number | string | boolean) { ->foo6 : Symbol(foo6, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 25, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 26, 14)) - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - return typeof x !== "string" // string | number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 26, 14)) - - && (typeof x !== "number" // number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 26, 14)) - - ? x // boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 26, 14)) - - : x === 10) // number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 26, 14)) -} -function foo7(x: number | string | boolean) { ->foo7 : Symbol(foo7, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 32, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) - - var y: number| boolean | string; ->y : Symbol(y, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 34, 7)) - - var z: number| boolean | string; ->z : Symbol(z, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 35, 7)) - - // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too - return typeof x !== "string" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) - - && ((z = x) // string | number | boolean - x changed deeper in conditional expression ->z : Symbol(z, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 35, 7)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) - - && (typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) - - // change value of x - ? (x = 10 && x.toString()) // number | boolean | string ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) ->x.toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) ->toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) - - // do not change value - : (y = x && x.toString()))); // number | boolean | string ->y : Symbol(y, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 34, 7)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) ->x.toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 33, 14)) ->toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) -} -function foo8(x: number | string) { ->foo8 : Symbol(foo8, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 45, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) - - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x !== "string" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) - - && (x = 10) // change x - number| string ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) - - && (typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) - - ? x // number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) - - : x.length); // string ->x.length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfAndAndOperator.ts, 46, 14)) ->length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) -} diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.types b/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.types deleted file mode 100644 index a3228352dac..00000000000 --- a/tests/baselines/reference/typeGuardsInRightOperandOfAndAndOperator.types +++ /dev/null @@ -1,234 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts === -// In the right operand of a && operation, -// the type of a variable or parameter is narrowed by any type guard in the left operand when true, -// provided the right operand contains no assignments to the variable or parameter. -function foo(x: number | string) { ->foo : (x: string | number) => boolean ->x : string | number - - return typeof x === "string" && x.length === 10; // string ->typeof x === "string" && x.length === 10 : boolean ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string ->x.length === 10 : boolean ->x.length : number ->x : string ->length : number ->10 : number -} -function foo2(x: number | string) { ->foo2 : (x: string | number) => string | number ->x : string | number - - // modify x in right hand operand - return typeof x === "string" && ((x = 10) && x); // string | number ->typeof x === "string" && ((x = 10) && x) : string | number ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string ->((x = 10) && x) : string | number ->(x = 10) && x : string | number ->(x = 10) : number ->x = 10 : number ->x : string | number ->10 : number ->x : string | number -} -function foo3(x: number | string) { ->foo3 : (x: string | number) => string | number ->x : string | number - - // modify x in right hand operand with string type itself - return typeof x === "string" && ((x = "hello") && x); // string | number ->typeof x === "string" && ((x = "hello") && x) : string | number ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string ->((x = "hello") && x) : string | number ->(x = "hello") && x : string | number ->(x = "hello") : string ->x = "hello" : string ->x : string | number ->"hello" : string ->x : string | number -} -function foo4(x: number | string | boolean) { ->foo4 : (x: string | number | boolean) => boolean ->x : string | number | boolean - - return typeof x !== "string" // string | number | boolean ->typeof x !== "string" // string | number | boolean && typeof x !== "number" // number | boolean && x : boolean ->typeof x !== "string" // string | number | boolean && typeof x !== "number" : boolean ->typeof x !== "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - && typeof x !== "number" // number | boolean ->typeof x !== "number" : boolean ->typeof x : string ->x : number | boolean ->"number" : string - - && x; // boolean ->x : boolean -} -function foo5(x: number | string | boolean) { ->foo5 : (x: string | number | boolean) => boolean ->x : string | number | boolean - - // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop - var b: number | boolean; ->b : number | boolean - - return typeof x !== "string" // string | number | boolean ->typeof x !== "string" // string | number | boolean && ((b = x) && (typeof x !== "number" // number | boolean && x)) : boolean ->typeof x !== "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - && ((b = x) && (typeof x !== "number" // number | boolean ->((b = x) && (typeof x !== "number" // number | boolean && x)) : boolean ->(b = x) && (typeof x !== "number" // number | boolean && x) : boolean ->(b = x) : number | boolean ->b = x : number | boolean ->b : number | boolean ->x : number | boolean ->(typeof x !== "number" // number | boolean && x) : boolean ->typeof x !== "number" // number | boolean && x : boolean ->typeof x !== "number" : boolean ->typeof x : string ->x : number | boolean ->"number" : string - - && x)); // boolean ->x : boolean -} -function foo6(x: number | string | boolean) { ->foo6 : (x: string | number | boolean) => boolean ->x : string | number | boolean - - // Mixing typeguard narrowing in if statement with conditional expression typeguard - return typeof x !== "string" // string | number | boolean ->typeof x !== "string" // string | number | boolean && (typeof x !== "number" // number | boolean ? x // boolean : x === 10) : boolean ->typeof x !== "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - && (typeof x !== "number" // number | boolean ->(typeof x !== "number" // number | boolean ? x // boolean : x === 10) : boolean ->typeof x !== "number" // number | boolean ? x // boolean : x === 10 : boolean ->typeof x !== "number" : boolean ->typeof x : string ->x : number | boolean ->"number" : string - - ? x // boolean ->x : boolean - - : x === 10) // number ->x === 10 : boolean ->x : number ->10 : number -} -function foo7(x: number | string | boolean) { ->foo7 : (x: string | number | boolean) => string ->x : string | number | boolean - - var y: number| boolean | string; ->y : string | number | boolean - - var z: number| boolean | string; ->z : string | number | boolean - - // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too - return typeof x !== "string" ->typeof x !== "string" && ((z = x) // string | number | boolean - x changed deeper in conditional expression && (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()))) : string ->typeof x !== "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - && ((z = x) // string | number | boolean - x changed deeper in conditional expression ->((z = x) // string | number | boolean - x changed deeper in conditional expression && (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()))) : string ->(z = x) // string | number | boolean - x changed deeper in conditional expression && (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString())) : string ->(z = x) : string | number | boolean ->z = x : string | number | boolean ->z : string | number | boolean ->x : string | number | boolean - - && (typeof x === "number" ->(typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString())) : string ->typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()) : string ->typeof x === "number" : boolean ->typeof x : string ->x : string | number | boolean ->"number" : string - - // change value of x - ? (x = 10 && x.toString()) // number | boolean | string ->(x = 10 && x.toString()) : string ->x = 10 && x.toString() : string ->x : string | number | boolean ->10 && x.toString() : string ->10 : number ->x.toString() : string ->x.toString : (() => string) | ((radix?: number) => string) ->x : string | number | boolean ->toString : (() => string) | ((radix?: number) => string) - - // do not change value - : (y = x && x.toString()))); // number | boolean | string ->(y = x && x.toString()) : string ->y = x && x.toString() : string ->y : string | number | boolean ->x && x.toString() : string ->x : string | number | boolean ->x.toString() : string ->x.toString : (() => string) | ((radix?: number) => string) ->x : string | number | boolean ->toString : (() => string) | ((radix?: number) => string) -} -function foo8(x: number | string) { ->foo8 : (x: string | number) => number ->x : string | number - - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x !== "string" ->typeof x !== "string" && (x = 10) // change x - number| string && (typeof x === "number" ? x // number : x.length) : number ->typeof x !== "string" && (x = 10) : number ->typeof x !== "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - && (x = 10) // change x - number| string ->(x = 10) : number ->x = 10 : number ->x : string | number ->10 : number - - && (typeof x === "number" ->(typeof x === "number" ? x // number : x.length) : number ->typeof x === "number" ? x // number : x.length : number ->typeof x === "number" : boolean ->typeof x : string ->x : string | number ->"number" : string - - ? x // number ->x : number - - : x.length); // string ->x.length : number ->x : string ->length : number -} diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.errors.txt b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.errors.txt new file mode 100644 index 00000000000..f34d035fa40 --- /dev/null +++ b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.errors.txt @@ -0,0 +1,64 @@ +tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfOrOrOperator.ts(43,22): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfOrOrOperator.ts(45,21): error TS2349: Cannot invoke an expression whose type lacks a call signature. + + +==== tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfOrOrOperator.ts (2 errors) ==== + // In the right operand of a || operation, + // the type of a variable or parameter is narrowed by any type guard in the left operand when false, + // provided the right operand contains no assignments to the variable or parameter. + function foo(x: number | string) { + return typeof x !== "string" || x.length === 10; // string + } + function foo2(x: number | string) { + // modify x in right hand operand + return typeof x !== "string" || ((x = 10) || x); // string | number + } + function foo3(x: number | string) { + // modify x in right hand operand with string type itself + return typeof x !== "string" || ((x = "hello") || x); // string | number + } + function foo4(x: number | string | boolean) { + return typeof x === "string" // string | number | boolean + || typeof x === "number" // number | boolean + || x; // boolean + } + function foo5(x: number | string | boolean) { + // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop + var b: number | boolean; + return typeof x === "string" // string | number | boolean + || ((b = x) || (typeof x === "number" // number | boolean + || x)); // boolean + } + function foo6(x: number | string | boolean) { + // Mixing typeguard + return typeof x === "string" // string | number | boolean + || (typeof x !== "number" // number | boolean + ? x // boolean + : x === 10) // number + } + function foo7(x: number | string | boolean) { + var y: number| boolean | string; + var z: number| boolean | string; + // Mixing typeguard narrowing + // Assigning value to x deep inside another guard stops narrowing of type too + return typeof x === "string" + || ((z = x) // string | number | boolean - x changed deeper in conditional expression + || (typeof x === "number" + // change value of x + ? (x = 10 && x.toString()) // number | boolean | string + ~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + // do not change value + : (y = x && x.toString()))); // number | boolean | string + ~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + } + function foo8(x: number | string) { + // Mixing typeguard + // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression + return typeof x === "string" + || (x = 10) // change x - number| string + || (typeof x === "number" + ? x // number + : x.length); // string + } \ No newline at end of file diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.symbols b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.symbols deleted file mode 100644 index dd751b7d8dd..00000000000 --- a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.symbols +++ /dev/null @@ -1,143 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfOrOrOperator.ts === -// In the right operand of a || operation, -// the type of a variable or parameter is narrowed by any type guard in the left operand when false, -// provided the right operand contains no assignments to the variable or parameter. -function foo(x: number | string) { ->foo : Symbol(foo, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 0, 0)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 3, 13)) - - return typeof x !== "string" || x.length === 10; // string ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 3, 13)) ->x.length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 3, 13)) ->length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) -} -function foo2(x: number | string) { ->foo2 : Symbol(foo2, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 5, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 6, 14)) - - // modify x in right hand operand - return typeof x !== "string" || ((x = 10) || x); // string | number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 6, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 6, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 6, 14)) -} -function foo3(x: number | string) { ->foo3 : Symbol(foo3, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 9, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 10, 14)) - - // modify x in right hand operand with string type itself - return typeof x !== "string" || ((x = "hello") || x); // string | number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 10, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 10, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 10, 14)) -} -function foo4(x: number | string | boolean) { ->foo4 : Symbol(foo4, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 13, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 14, 14)) - - return typeof x === "string" // string | number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 14, 14)) - - || typeof x === "number" // number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 14, 14)) - - || x; // boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 14, 14)) -} -function foo5(x: number | string | boolean) { ->foo5 : Symbol(foo5, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 18, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 19, 14)) - - // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop - var b: number | boolean; ->b : Symbol(b, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 21, 7)) - - return typeof x === "string" // string | number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 19, 14)) - - || ((b = x) || (typeof x === "number" // number | boolean ->b : Symbol(b, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 21, 7)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 19, 14)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 19, 14)) - - || x)); // boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 19, 14)) -} -function foo6(x: number | string | boolean) { ->foo6 : Symbol(foo6, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 25, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 26, 14)) - - // Mixing typeguard - return typeof x === "string" // string | number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 26, 14)) - - || (typeof x !== "number" // number | boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 26, 14)) - - ? x // boolean ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 26, 14)) - - : x === 10) // number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 26, 14)) -} -function foo7(x: number | string | boolean) { ->foo7 : Symbol(foo7, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 32, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) - - var y: number| boolean | string; ->y : Symbol(y, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 34, 7)) - - var z: number| boolean | string; ->z : Symbol(z, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 35, 7)) - - // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) - - || ((z = x) // string | number | boolean - x changed deeper in conditional expression ->z : Symbol(z, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 35, 7)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) - - || (typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) - - // change value of x - ? (x = 10 && x.toString()) // number | boolean | string ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) ->x.toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) ->toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) - - // do not change value - : (y = x && x.toString()))); // number | boolean | string ->y : Symbol(y, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 34, 7)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) ->x.toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 33, 14)) ->toString : Symbol(toString, Decl(lib.d.ts, 277, 18), Decl(lib.d.ts, 458, 18), Decl(lib.d.ts, 96, 26)) -} -function foo8(x: number | string) { ->foo8 : Symbol(foo8, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 45, 1)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) - - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x === "string" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) - - || (x = 10) // change x - number| string ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) - - || (typeof x === "number" ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) - - ? x // number ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) - - : x.length); // string ->x.length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) ->x : Symbol(x, Decl(typeGuardsInRightOperandOfOrOrOperator.ts, 46, 14)) ->length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) -} diff --git a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.types b/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.types deleted file mode 100644 index b997189dd0c..00000000000 --- a/tests/baselines/reference/typeGuardsInRightOperandOfOrOrOperator.types +++ /dev/null @@ -1,234 +0,0 @@ -=== tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfOrOrOperator.ts === -// In the right operand of a || operation, -// the type of a variable or parameter is narrowed by any type guard in the left operand when false, -// provided the right operand contains no assignments to the variable or parameter. -function foo(x: number | string) { ->foo : (x: string | number) => boolean ->x : string | number - - return typeof x !== "string" || x.length === 10; // string ->typeof x !== "string" || x.length === 10 : boolean ->typeof x !== "string" : boolean ->typeof x : string ->x : string | number ->"string" : string ->x.length === 10 : boolean ->x.length : number ->x : string ->length : number ->10 : number -} -function foo2(x: number | string) { ->foo2 : (x: string | number) => string | number | boolean ->x : string | number - - // modify x in right hand operand - return typeof x !== "string" || ((x = 10) || x); // string | number ->typeof x !== "string" || ((x = 10) || x) : string | number | boolean ->typeof x !== "string" : boolean ->typeof x : string ->x : string | number ->"string" : string ->((x = 10) || x) : string | number ->(x = 10) || x : string | number ->(x = 10) : number ->x = 10 : number ->x : string | number ->10 : number ->x : string | number -} -function foo3(x: number | string) { ->foo3 : (x: string | number) => string | number | boolean ->x : string | number - - // modify x in right hand operand with string type itself - return typeof x !== "string" || ((x = "hello") || x); // string | number ->typeof x !== "string" || ((x = "hello") || x) : string | number | boolean ->typeof x !== "string" : boolean ->typeof x : string ->x : string | number ->"string" : string ->((x = "hello") || x) : string | number ->(x = "hello") || x : string | number ->(x = "hello") : string ->x = "hello" : string ->x : string | number ->"hello" : string ->x : string | number -} -function foo4(x: number | string | boolean) { ->foo4 : (x: string | number | boolean) => boolean ->x : string | number | boolean - - return typeof x === "string" // string | number | boolean ->typeof x === "string" // string | number | boolean || typeof x === "number" // number | boolean || x : boolean ->typeof x === "string" // string | number | boolean || typeof x === "number" : boolean ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - || typeof x === "number" // number | boolean ->typeof x === "number" : boolean ->typeof x : string ->x : number | boolean ->"number" : string - - || x; // boolean ->x : boolean -} -function foo5(x: number | string | boolean) { ->foo5 : (x: string | number | boolean) => number | boolean ->x : string | number | boolean - - // usage of x or assignment to separate variable shouldn't cause narrowing of type to stop - var b: number | boolean; ->b : number | boolean - - return typeof x === "string" // string | number | boolean ->typeof x === "string" // string | number | boolean || ((b = x) || (typeof x === "number" // number | boolean || x)) : number | boolean ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - || ((b = x) || (typeof x === "number" // number | boolean ->((b = x) || (typeof x === "number" // number | boolean || x)) : number | boolean ->(b = x) || (typeof x === "number" // number | boolean || x) : number | boolean ->(b = x) : number | boolean ->b = x : number | boolean ->b : number | boolean ->x : number | boolean ->(typeof x === "number" // number | boolean || x) : boolean ->typeof x === "number" // number | boolean || x : boolean ->typeof x === "number" : boolean ->typeof x : string ->x : number | boolean ->"number" : string - - || x)); // boolean ->x : boolean -} -function foo6(x: number | string | boolean) { ->foo6 : (x: string | number | boolean) => boolean ->x : string | number | boolean - - // Mixing typeguard - return typeof x === "string" // string | number | boolean ->typeof x === "string" // string | number | boolean || (typeof x !== "number" // number | boolean ? x // boolean : x === 10) : boolean ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - || (typeof x !== "number" // number | boolean ->(typeof x !== "number" // number | boolean ? x // boolean : x === 10) : boolean ->typeof x !== "number" // number | boolean ? x // boolean : x === 10 : boolean ->typeof x !== "number" : boolean ->typeof x : string ->x : number | boolean ->"number" : string - - ? x // boolean ->x : boolean - - : x === 10) // number ->x === 10 : boolean ->x : number ->10 : number -} -function foo7(x: number | string | boolean) { ->foo7 : (x: string | number | boolean) => string | number | boolean ->x : string | number | boolean - - var y: number| boolean | string; ->y : string | number | boolean - - var z: number| boolean | string; ->z : string | number | boolean - - // Mixing typeguard narrowing - // Assigning value to x deep inside another guard stops narrowing of type too - return typeof x === "string" ->typeof x === "string" || ((z = x) // string | number | boolean - x changed deeper in conditional expression || (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()))) : string | number | boolean ->typeof x === "string" : boolean ->typeof x : string ->x : string | number | boolean ->"string" : string - - || ((z = x) // string | number | boolean - x changed deeper in conditional expression ->((z = x) // string | number | boolean - x changed deeper in conditional expression || (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()))) : string | number | boolean ->(z = x) // string | number | boolean - x changed deeper in conditional expression || (typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString())) : string | number | boolean ->(z = x) : string | number | boolean ->z = x : string | number | boolean ->z : string | number | boolean ->x : string | number | boolean - - || (typeof x === "number" ->(typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString())) : string ->typeof x === "number" // change value of x ? (x = 10 && x.toString()) // number | boolean | string // do not change value : (y = x && x.toString()) : string ->typeof x === "number" : boolean ->typeof x : string ->x : string | number | boolean ->"number" : string - - // change value of x - ? (x = 10 && x.toString()) // number | boolean | string ->(x = 10 && x.toString()) : string ->x = 10 && x.toString() : string ->x : string | number | boolean ->10 && x.toString() : string ->10 : number ->x.toString() : string ->x.toString : (() => string) | ((radix?: number) => string) ->x : string | number | boolean ->toString : (() => string) | ((radix?: number) => string) - - // do not change value - : (y = x && x.toString()))); // number | boolean | string ->(y = x && x.toString()) : string ->y = x && x.toString() : string ->y : string | number | boolean ->x && x.toString() : string ->x : string | number | boolean ->x.toString() : string ->x.toString : (() => string) | ((radix?: number) => string) ->x : string | number | boolean ->toString : (() => string) | ((radix?: number) => string) -} -function foo8(x: number | string) { ->foo8 : (x: string | number) => number | boolean ->x : string | number - - // Mixing typeguard - // Assigning value to x in outer guard shouldn't stop narrowing in the inner expression - return typeof x === "string" ->typeof x === "string" || (x = 10) // change x - number| string || (typeof x === "number" ? x // number : x.length) : number | boolean ->typeof x === "string" || (x = 10) : number | boolean ->typeof x === "string" : boolean ->typeof x : string ->x : string | number ->"string" : string - - || (x = 10) // change x - number| string ->(x = 10) : number ->x = 10 : number ->x : string | number ->10 : number - - || (typeof x === "number" ->(typeof x === "number" ? x // number : x.length) : number ->typeof x === "number" ? x // number : x.length : number ->typeof x === "number" : boolean ->typeof x : string ->x : string | number ->"number" : string - - ? x // number ->x : number - - : x.length); // string ->x.length : number ->x : string ->length : number -} diff --git a/tests/baselines/reference/unionTypeCallSignatures.errors.txt b/tests/baselines/reference/unionTypeCallSignatures.errors.txt index 313cd477187..c25a2bf9f84 100644 --- a/tests/baselines/reference/unionTypeCallSignatures.errors.txt +++ b/tests/baselines/reference/unionTypeCallSignatures.errors.txt @@ -5,9 +5,8 @@ tests/cases/conformance/types/union/unionTypeCallSignatures.ts(16,1): error TS23 tests/cases/conformance/types/union/unionTypeCallSignatures.ts(19,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(20,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(21,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. -tests/cases/conformance/types/union/unionTypeCallSignatures.ts(24,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. -tests/cases/conformance/types/union/unionTypeCallSignatures.ts(25,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. -tests/cases/conformance/types/union/unionTypeCallSignatures.ts(26,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(24,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(26,36): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(29,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(30,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. tests/cases/conformance/types/union/unionTypeCallSignatures.ts(31,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. @@ -35,7 +34,7 @@ tests/cases/conformance/types/union/unionTypeCallSignatures.ts(69,12): error TS2 tests/cases/conformance/types/union/unionTypeCallSignatures.ts(70,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. -==== tests/cases/conformance/types/union/unionTypeCallSignatures.ts (35 errors) ==== +==== tests/cases/conformance/types/union/unionTypeCallSignatures.ts (34 errors) ==== var numOrDate: number | Date; var strOrBoolean: string | boolean; var strOrNum: string | number; @@ -75,13 +74,11 @@ tests/cases/conformance/types/union/unionTypeCallSignatures.ts(70,12): error TS2 var unionOfDifferentNumberOfSignatures: { (a: number): number; } | { (a: number): Date; (a: string): boolean; }; unionOfDifferentNumberOfSignatures(); // error - no call signatures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. +!!! error TS2346: Supplied parameters do not match any signature of call target. unionOfDifferentNumberOfSignatures(10); // error - no call signatures - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. unionOfDifferentNumberOfSignatures("hello"); // error - no call signatures - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + ~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. var unionWithDifferentParameterCount: { (a: string): string; } | { (a: string, b: number): number; } ; unionWithDifferentParameterCount();// no call signature diff --git a/tests/baselines/reference/unionTypeConstructSignatures.errors.txt b/tests/baselines/reference/unionTypeConstructSignatures.errors.txt index dd46564d779..cbdcc9ed12a 100644 --- a/tests/baselines/reference/unionTypeConstructSignatures.errors.txt +++ b/tests/baselines/reference/unionTypeConstructSignatures.errors.txt @@ -5,9 +5,8 @@ tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(16,1): error tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(19,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(20,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(21,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. -tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(24,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. -tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(25,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. -tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(26,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(24,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(26,40): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(29,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(30,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(31,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. @@ -35,7 +34,7 @@ tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(69,12): erro tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(70,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. -==== tests/cases/conformance/types/union/unionTypeConstructSignatures.ts (35 errors) ==== +==== tests/cases/conformance/types/union/unionTypeConstructSignatures.ts (34 errors) ==== var numOrDate: number | Date; var strOrBoolean: string | boolean; var strOrNum: string | number; @@ -75,13 +74,11 @@ tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(70,12): erro var unionOfDifferentNumberOfSignatures: { new (a: number): number; } | { new (a: number): Date; new (a: string): boolean; }; new unionOfDifferentNumberOfSignatures(); // error - no call signatures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +!!! error TS2346: Supplied parameters do not match any signature of call target. new unionOfDifferentNumberOfSignatures(10); // error - no call signatures - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. new unionOfDifferentNumberOfSignatures("hello"); // error - no call signatures - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + ~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. var unionWithDifferentParameterCount: { new (a: string): string; } | { new (a: string, b: number): number; }; new unionWithDifferentParameterCount();// no call signature