mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-12 01:29:50 -05:00
Accepting new baselines
This commit is contained in:
35
tests/baselines/reference/arrayOfFunctionTypes3.errors.txt
Normal file
35
tests/baselines/reference/arrayOfFunctionTypes3.errors.txt
Normal file
@@ -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: { <T>(x: T): number; (x: string): string;};
|
||||
var b2: { <T>(x: T): number; (x: string): string; };
|
||||
var c2: { (x: number): number; <T>(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.
|
||||
@@ -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: { <T>(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: { <T>(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; <T>(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))
|
||||
|
||||
@@ -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: { <T>(x: T): number; (x: string): string;};
|
||||
>a2 : { <T>(x: T): number; (x: string): string; }
|
||||
>T : T
|
||||
>x : T
|
||||
>T : T
|
||||
>x : string
|
||||
|
||||
var b2: { <T>(x: T): number; (x: string): string; };
|
||||
>b2 : { <T>(x: T): number; (x: string): string; }
|
||||
>T : T
|
||||
>x : T
|
||||
>T : T
|
||||
>x : string
|
||||
|
||||
var c2: { (x: number): number; <T>(x: T): any; };
|
||||
>c2 : { (x: number): number; <T>(x: T): any; }
|
||||
>x : number
|
||||
>T : T
|
||||
>x : T
|
||||
>T : T
|
||||
|
||||
var z2 = [a2, b2, c2];
|
||||
>z2 : ({ <T>(x: T): number; (x: string): string; } | { (x: number): number; <T>(x: T): any; })[]
|
||||
>[a2, b2, c2] : ({ <T>(x: T): number; (x: string): string; } | { (x: number): number; <T>(x: T): any; })[]
|
||||
>a2 : { <T>(x: T): number; (x: string): string; }
|
||||
>b2 : { <T>(x: T): number; (x: string): string; }
|
||||
>c2 : { (x: number): number; <T>(x: T): any; }
|
||||
|
||||
var r6 = z2[0];
|
||||
>r6 : { <T>(x: T): number; (x: string): string; } | { (x: number): number; <T>(x: T): any; }
|
||||
>z2[0] : { <T>(x: T): number; (x: string): string; } | { (x: number): number; <T>(x: T): any; }
|
||||
>z2 : ({ <T>(x: T): number; (x: string): string; } | { (x: number): number; <T>(x: T): any; })[]
|
||||
>0 : number
|
||||
|
||||
var r7 = r6(''); // any not string
|
||||
>r7 : any
|
||||
>r6('') : any
|
||||
>r6 : { <T>(x: T): number; (x: string): string; } | { (x: number): number; <T>(x: T): any; }
|
||||
>'' : string
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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<T, U>(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<any, any>([1, ""], (x) => x.toString());
|
||||
var r6 = map<Object, Object>([1, ""], (x) => x.toString());
|
||||
var r7 = map<number, string>([1, ""], (x) => x.toString()); // error
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
160
tests/baselines/reference/typeGuardsInIfStatement.errors.txt
Normal file
160
tests/baselines/reference/typeGuardsInIfStatement.errors.txt
Normal file
@@ -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 <20>if<69> statement,
|
||||
// the type of a variable or parameter is narrowed by any type guard in the <20>if<69> condition when true,
|
||||
// provided the true branch statement contains no assignments to the variable or parameter.
|
||||
// In the false branch statement of an <20>if<69> statement,
|
||||
// the type of a variable or parameter is narrowed by any type guard in the <20>if<69> 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
|
||||
}
|
||||
}
|
||||
@@ -1,304 +0,0 @@
|
||||
=== tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts ===
|
||||
// In the true branch statement of an <20>if<69> statement,
|
||||
// the type of a variable or parameter is narrowed by any type guard in the <20>if<69> condition when true,
|
||||
// provided the true branch statement contains no assignments to the variable or parameter.
|
||||
// In the false branch statement of an <20>if<69> statement,
|
||||
// the type of a variable or parameter is narrowed by any type guard in the <20>if<69> 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))
|
||||
}
|
||||
}
|
||||
@@ -1,405 +0,0 @@
|
||||
=== tests/cases/conformance/expressions/typeGuards/typeGuardsInIfStatement.ts ===
|
||||
// In the true branch statement of an <20>if<69> statement,
|
||||
// the type of a variable or parameter is narrowed by any type guard in the <20>if<69> condition when true,
|
||||
// provided the true branch statement contains no assignments to the variable or parameter.
|
||||
// In the false branch statement of an <20>if<69> statement,
|
||||
// the type of a variable or parameter is narrowed by any type guard in the <20>if<69> 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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user