Do not publicly expose a way on a Program instance to get typecheckers with differing behavior.

Now, you can only get the non-diagnostics, pull-type-checker from the Program instance.
If you want diagnostics, you simply ask the Program instance for the diagnostics you want.
This commit is contained in:
Cyrus Najmabadi
2015-02-04 16:11:38 -08:00
parent 5b049feb36
commit b6d083fa40
25 changed files with 2145 additions and 69 deletions

View File

@@ -740,12 +740,13 @@ declare module "typescript" {
interface Program extends ScriptReferenceHost {
getSourceFiles(): SourceFile[];
getCompilerHost(): CompilerHost;
getEmitResolver(): EmitResolver;
getTypeCheckerDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getTypeCheckerGlobalDiagnostics(): Diagnostic[];
getDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getGlobalDiagnostics(): Diagnostic[];
getDeclarationDiagnostics(sourceFile: SourceFile): Diagnostic[];
getTypeChecker(produceDiagnostics: boolean): TypeChecker;
getTypeChecker(): TypeChecker;
getCommonSourceDirectory(): string;
emitFiles(targetSourceFile?: SourceFile): EmitResult;
isEmitBlocked(sourceFile?: SourceFile): boolean;
@@ -789,7 +790,6 @@ declare module "typescript" {
getSourceFile(fileName: string): SourceFile;
}
interface TypeChecker {
getEmitResolver(): EmitResolver;
getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type;
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
getPropertiesOfType(type: Type): Symbol[];

View File

@@ -2253,6 +2253,10 @@ declare module "typescript" {
argumentExpression?: Expression;
>argumentExpression : Expression
>Expression : Expression
}
interface CallExpression extends LeftHandSideExpression {
>CallExpression : CallExpression
@@ -2279,9 +2283,8 @@ declare module "typescript" {
interface NewExpression extends CallExpression, PrimaryExpression {
>NewExpression : NewExpression
interface NewExpression extends CallExpression, PrimaryExpression {
>CallExpression : CallExpression
>PrimaryExpression : PrimaryExpression
}
interface TaggedTemplateExpression extends MemberExpression {
@@ -2409,10 +2412,6 @@ declare module "typescript" {
expression: Expression;
>expression : Expression
expression: Expression;
>expression : Expression
>Expression : Expression
>Expression : Expression
}

View File

@@ -770,12 +770,13 @@ declare module "typescript" {
interface Program extends ScriptReferenceHost {
getSourceFiles(): SourceFile[];
getCompilerHost(): CompilerHost;
getEmitResolver(): EmitResolver;
getTypeCheckerDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getTypeCheckerGlobalDiagnostics(): Diagnostic[];
getDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getGlobalDiagnostics(): Diagnostic[];
getDeclarationDiagnostics(sourceFile: SourceFile): Diagnostic[];
getTypeChecker(produceDiagnostics: boolean): TypeChecker;
getTypeChecker(): TypeChecker;
getCommonSourceDirectory(): string;
emitFiles(targetSourceFile?: SourceFile): EmitResult;
isEmitBlocked(sourceFile?: SourceFile): boolean;
@@ -819,7 +820,6 @@ declare module "typescript" {
getSourceFile(fileName: string): SourceFile;
}
interface TypeChecker {
getEmitResolver(): EmitResolver;
getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type;
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
getPropertiesOfType(type: Type): Symbol[];

View File

@@ -2391,6 +2391,10 @@ declare module "typescript" {
argumentExpression?: Expression;
>argumentExpression : Expression
>Expression : Expression
}
interface CallExpression extends LeftHandSideExpression {
>CallExpression : CallExpression
@@ -2417,9 +2421,8 @@ declare module "typescript" {
interface NewExpression extends CallExpression, PrimaryExpression {
>NewExpression : NewExpression
interface NewExpression extends CallExpression, PrimaryExpression {
>CallExpression : CallExpression
>PrimaryExpression : PrimaryExpression
}
interface TaggedTemplateExpression extends MemberExpression {
@@ -2547,10 +2550,6 @@ declare module "typescript" {
expression: Expression;
>expression : Expression
expression: Expression;
>expression : Expression
>Expression : Expression
>Expression : Expression
}

View File

@@ -770,12 +770,13 @@ declare module "typescript" {
interface Program extends ScriptReferenceHost {
getSourceFiles(): SourceFile[];
getCompilerHost(): CompilerHost;
getEmitResolver(): EmitResolver;
getTypeCheckerDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getTypeCheckerGlobalDiagnostics(): Diagnostic[];
getDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getGlobalDiagnostics(): Diagnostic[];
getDeclarationDiagnostics(sourceFile: SourceFile): Diagnostic[];
getTypeChecker(produceDiagnostics: boolean): TypeChecker;
getTypeChecker(): TypeChecker;
getCommonSourceDirectory(): string;
emitFiles(targetSourceFile?: SourceFile): EmitResult;
isEmitBlocked(sourceFile?: SourceFile): boolean;
@@ -819,7 +820,6 @@ declare module "typescript" {
getSourceFile(fileName: string): SourceFile;
}
interface TypeChecker {
getEmitResolver(): EmitResolver;
getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type;
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
getPropertiesOfType(type: Type): Symbol[];

View File

@@ -2332,6 +2332,10 @@ declare module "typescript" {
argumentExpression?: Expression;
>argumentExpression : Expression
>Expression : Expression
}
interface CallExpression extends LeftHandSideExpression {
>CallExpression : CallExpression
@@ -2358,9 +2362,8 @@ declare module "typescript" {
interface NewExpression extends CallExpression, PrimaryExpression {
>NewExpression : NewExpression
interface NewExpression extends CallExpression, PrimaryExpression {
>CallExpression : CallExpression
>PrimaryExpression : PrimaryExpression
}
interface TaggedTemplateExpression extends MemberExpression {
@@ -2488,10 +2491,6 @@ declare module "typescript" {
expression: Expression;
>expression : Expression
expression: Expression;
>expression : Expression
>Expression : Expression
>Expression : Expression
}

View File

@@ -808,12 +808,13 @@ declare module "typescript" {
interface Program extends ScriptReferenceHost {
getSourceFiles(): SourceFile[];
getCompilerHost(): CompilerHost;
getEmitResolver(): EmitResolver;
getTypeCheckerDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getTypeCheckerGlobalDiagnostics(): Diagnostic[];
getDiagnostics(sourceFile?: SourceFile): Diagnostic[];
getGlobalDiagnostics(): Diagnostic[];
getDeclarationDiagnostics(sourceFile: SourceFile): Diagnostic[];
getTypeChecker(produceDiagnostics: boolean): TypeChecker;
getTypeChecker(): TypeChecker;
getCommonSourceDirectory(): string;
emitFiles(targetSourceFile?: SourceFile): EmitResult;
isEmitBlocked(sourceFile?: SourceFile): boolean;
@@ -857,7 +858,6 @@ declare module "typescript" {
getSourceFile(fileName: string): SourceFile;
}
interface TypeChecker {
getEmitResolver(): EmitResolver;
getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type;
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
getPropertiesOfType(type: Type): Symbol[];

View File

@@ -2517,6 +2517,10 @@ declare module "typescript" {
argumentExpression?: Expression;
>argumentExpression : Expression
>Expression : Expression
}
interface CallExpression extends LeftHandSideExpression {
>CallExpression : CallExpression
@@ -2543,9 +2547,8 @@ declare module "typescript" {
interface NewExpression extends CallExpression, PrimaryExpression {
>NewExpression : NewExpression
interface NewExpression extends CallExpression, PrimaryExpression {
>CallExpression : CallExpression
>PrimaryExpression : PrimaryExpression
}
interface TaggedTemplateExpression extends MemberExpression {
@@ -2673,10 +2676,6 @@ declare module "typescript" {
expression: Expression;
>expression : Expression
expression: Expression;
>expression : Expression
>Expression : Expression
>Expression : Expression
}

View File

@@ -0,0 +1,96 @@
=== tests/cases/conformance/expressions/typeGuards/TypeGuardWithEnumUnion.ts ===
enum Color { R, G, B }
>Color : Color
>R : Color
>G : Color
>B : Color
function f1(x: Color | string) {
>f1 : (x: string | Color) => void
>x : string | Color
>Color : Color
if (typeof x === "number") {
>typeof x === "number" : boolean
>typeof x : string
>x : string | Color
var y = x;
>y : Color
>x : Color
var y: Color;
>y : Color
>Color : Color
}
else {
var z = x;
>z : string
>x : string
var z: string;
>z : string
}
}
function f2(x: Color | string | string[]) {
>f2 : (x: string | Color | string[]) => void
>x : string | Color | string[]
>Color : Color
if (typeof x === "object") {
>typeof x === "object" : boolean
>typeof x : string
>x : string | Color | string[]
var y = x;
>y : string[]
>x : string[]
var y: string[];
>y : string[]
}
if (typeof x === "number") {
>typeof x === "number" : boolean
>typeof x : string
>x : string | Color | string[]
var z = x;
>z : Color
>x : Color
var z: Color;
>z : Color
>Color : Color
}
else {
var w = x;
>w : string | string[]
>x : string | string[]
var w: string | string[];
>w : string | string[]
}
if (typeof x === "string") {
>typeof x === "string" : boolean
>typeof x : string
>x : string | Color | string[]
var a = x;
>a : string
>x : string
var a: string;
>a : string
}
else {
var b = x;
>b : Color | string[]
>x : Color | string[]
var b: Color | string[];
>b : Color | string[]
>Color : Color
}
}

View File

@@ -0,0 +1,83 @@
=== tests/cases/compiler/aliasUsageInOrExpression_main.ts ===
import Backbone = require("aliasUsageInOrExpression_backbone");
>Backbone : typeof Backbone
import moduleA = require("aliasUsageInOrExpression_moduleA");
>moduleA : typeof moduleA
interface IHasVisualizationModel {
>IHasVisualizationModel : IHasVisualizationModel
VisualizationModel: typeof Backbone.Model;
>VisualizationModel : typeof Backbone.Model
>Backbone : typeof Backbone
>Model : typeof Backbone.Model
}
var i: IHasVisualizationModel;
>i : IHasVisualizationModel
>IHasVisualizationModel : IHasVisualizationModel
var d1 = i || moduleA;
>d1 : typeof moduleA
>i || moduleA : typeof moduleA
>i : IHasVisualizationModel
>moduleA : typeof moduleA
var d2: IHasVisualizationModel = i || moduleA;
>d2 : IHasVisualizationModel
>IHasVisualizationModel : IHasVisualizationModel
>i || moduleA : typeof moduleA
>i : IHasVisualizationModel
>moduleA : typeof moduleA
var d2: IHasVisualizationModel = moduleA || i;
>d2 : IHasVisualizationModel
>IHasVisualizationModel : IHasVisualizationModel
>moduleA || i : typeof moduleA
>moduleA : typeof moduleA
>i : IHasVisualizationModel
var e: { x: IHasVisualizationModel } = <{ x: IHasVisualizationModel }>null || { x: moduleA };
>e : { x: IHasVisualizationModel; }
>x : IHasVisualizationModel
>IHasVisualizationModel : IHasVisualizationModel
><{ x: IHasVisualizationModel }>null || { x: moduleA } : { x: IHasVisualizationModel; }
><{ x: IHasVisualizationModel }>null : { x: IHasVisualizationModel; }
>x : IHasVisualizationModel
>IHasVisualizationModel : IHasVisualizationModel
>{ x: moduleA } : { x: typeof moduleA; }
>x : typeof moduleA
>moduleA : typeof moduleA
var f: { x: IHasVisualizationModel } = <{ x: IHasVisualizationModel }>null ? { x: moduleA } : null;
>f : { x: IHasVisualizationModel; }
>x : IHasVisualizationModel
>IHasVisualizationModel : IHasVisualizationModel
><{ x: IHasVisualizationModel }>null ? { x: moduleA } : null : { x: typeof moduleA; }
><{ x: IHasVisualizationModel }>null : { x: IHasVisualizationModel; }
>x : IHasVisualizationModel
>IHasVisualizationModel : IHasVisualizationModel
>{ x: moduleA } : { x: typeof moduleA; }
>x : typeof moduleA
>moduleA : typeof moduleA
=== tests/cases/compiler/aliasUsageInOrExpression_backbone.ts ===
export class Model {
>Model : Model
public someData: string;
>someData : string
}
=== tests/cases/compiler/aliasUsageInOrExpression_moduleA.ts ===
import Backbone = require("aliasUsageInOrExpression_backbone");
>Backbone : typeof Backbone
export class VisualizationModel extends Backbone.Model {
>VisualizationModel : VisualizationModel
>Backbone : unknown
>Model : Backbone.Model
// interesting stuff here
}

View File

@@ -0,0 +1,124 @@
=== tests/cases/conformance/expressions/arrayLiterals/arrayLiterals.ts ===
// Empty array literal with no contextual type has type Undefined[]
var arr1= [[], [1], ['']];
>arr1 : (number[] | string[])[]
>[[], [1], ['']] : (number[] | string[])[]
>[] : undefined[]
>[1] : number[]
>[''] : string[]
var arr2 = [[null], [1], ['']];
>arr2 : (number[] | string[])[]
>[[null], [1], ['']] : (number[] | string[])[]
>[null] : null[]
>[1] : number[]
>[''] : string[]
// Array literal with elements of only EveryType E has type E[]
var stringArrArr = [[''], [""]];
>stringArrArr : string[][]
>[[''], [""]] : string[][]
>[''] : string[]
>[""] : string[]
var stringArr = ['', ""];
>stringArr : string[]
>['', ""] : string[]
var numberArr = [0, 0.0, 0x00, 1e1];
>numberArr : number[]
>[0, 0.0, 0x00, 1e1] : number[]
var boolArr = [false, true, false, true];
>boolArr : boolean[]
>[false, true, false, true] : boolean[]
class C { private p; }
>C : C
>p : any
var classArr = [new C(), new C()];
>classArr : C[]
>[new C(), new C()] : C[]
>new C() : C
>C : typeof C
>new C() : C
>C : typeof C
var classTypeArray = [C, C, C];
>classTypeArray : typeof C[]
>[C, C, C] : typeof C[]
>C : typeof C
>C : typeof C
>C : typeof C
var classTypeArray: Array<typeof C>; // Should OK, not be a parse error
>classTypeArray : typeof C[]
>Array : T[]
>C : typeof C
// Contextual type C with numeric index signature makes array literal of EveryType E of type BCT(E,C)[]
var context1: { [n: number]: { a: string; b: number; }; } = [{ a: '', b: 0, c: '' }, { a: "", b: 3, c: 0 }];
>context1 : { [n: number]: { a: string; b: number; }; }
>n : number
>a : string
>b : number
>[{ a: '', b: 0, c: '' }, { a: "", b: 3, c: 0 }] : ({ a: string; b: number; c: string; } | { a: string; b: number; c: number; })[]
>{ a: '', b: 0, c: '' } : { a: string; b: number; c: string; }
>a : string
>b : number
>c : string
>{ a: "", b: 3, c: 0 } : { a: string; b: number; c: number; }
>a : string
>b : number
>c : number
var context2 = [{ a: '', b: 0, c: '' }, { a: "", b: 3, c: 0 }];
>context2 : ({ a: string; b: number; c: string; } | { a: string; b: number; c: number; })[]
>[{ a: '', b: 0, c: '' }, { a: "", b: 3, c: 0 }] : ({ a: string; b: number; c: string; } | { a: string; b: number; c: number; })[]
>{ a: '', b: 0, c: '' } : { a: string; b: number; c: string; }
>a : string
>b : number
>c : string
>{ a: "", b: 3, c: 0 } : { a: string; b: number; c: number; }
>a : string
>b : number
>c : number
// Contextual type C with numeric index signature of type Base makes array literal of Derived have type Base[]
class Base { private p; }
>Base : Base
>p : any
class Derived1 extends Base { private m };
>Derived1 : Derived1
>Base : Base
>m : any
class Derived2 extends Base { private n };
>Derived2 : Derived2
>Base : Base
>n : any
var context3: Base[] = [new Derived1(), new Derived2()];
>context3 : Base[]
>Base : Base
>[new Derived1(), new Derived2()] : (Derived1 | Derived2)[]
>new Derived1() : Derived1
>Derived1 : typeof Derived1
>new Derived2() : Derived2
>Derived2 : typeof Derived2
// Contextual type C with numeric index signature of type Base makes array literal of Derived1 and Derived2 have type Base[]
var context4: Base[] = [new Derived1(), new Derived1()];
>context4 : Base[]
>Base : Base
>[new Derived1(), new Derived1()] : Derived1[]
>new Derived1() : Derived1
>Derived1 : typeof Derived1
>new Derived1() : Derived1
>Derived1 : typeof Derived1

View File

@@ -0,0 +1,40 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType6.ts ===
interface I<T> {
>I : I<T>
>T : T
[s: string]: T;
>s : string
>T : T
}
declare function foo<T>(obj: I<T>): T
>foo : <T>(obj: I<T>) => T
>T : T
>obj : I<T>
>I : I<T>
>T : T
>T : T
foo({
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : string | number | boolean | (() => void) | number[]
>foo : <T>(obj: I<T>) => T
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: string]: string | number | boolean | (() => void) | number[]; 0: () => void; p: string; }
p: "",
>p : string
0: () => { },
>() => { } : () => void
["hi" + "bye"]: true,
>"hi" + "bye" : string
[0 + 1]: 0,
>0 + 1 : number
[+"hi"]: [0]
>+"hi" : number
>[0] : number[]
});

View File

@@ -0,0 +1,40 @@
=== tests/cases/conformance/es6/computedProperties/computedPropertyNamesContextualType7.ts ===
interface I<T> {
>I : I<T>
>T : T
[s: number]: T;
>s : number
>T : T
}
declare function foo<T>(obj: I<T>): T
>foo : <T>(obj: I<T>) => T
>T : T
>obj : I<T>
>I : I<T>
>T : T
>T : T
foo({
>foo({ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]}) : number | (() => void) | number[]
>foo : <T>(obj: I<T>) => T
>{ p: "", 0: () => { }, ["hi" + "bye"]: true, [0 + 1]: 0, [+"hi"]: [0]} : { [x: number]: number | (() => void) | number[]; 0: () => void; p: string; }
p: "",
>p : string
0: () => { },
>() => { } : () => void
["hi" + "bye"]: true,
>"hi" + "bye" : string
[0 + 1]: 0,
>0 + 1 : number
[+"hi"]: [0]
>+"hi" : number
>[0] : number[]
});

View File

@@ -0,0 +1,142 @@
=== tests/cases/conformance/types/typeRelationships/typeInference/contextualSignatureInstantiation.ts ===
// TypeScript Spec, section 4.12.2:
// If e is an expression of a function type that contains exactly one generic call signature and no other members,
// and T is a function type with exactly one non - generic call signature and no other members, then any inferences
// made for type parameters referenced by the parameters of T's call signature are fixed, and e's type is changed
// to a function type with e's call signature instantiated in the context of T's call signature (section 3.8.5).
declare function foo<T>(cb: (x: number, y: string) => T): T;
>foo : <T>(cb: (x: number, y: string) => T) => T
>T : T
>cb : (x: number, y: string) => T
>x : number
>y : string
>T : T
>T : T
declare function bar<T, U, V>(x: T, y: U, cb: (x: T, y: U) => V): V;
>bar : <T, U, V>(x: T, y: U, cb: (x: T, y: U) => V) => V
>T : T
>U : U
>V : V
>x : T
>T : T
>y : U
>U : U
>cb : (x: T, y: U) => V
>x : T
>T : T
>y : U
>U : U
>V : V
>V : V
declare function baz<T, U>(x: T, y: T, cb: (x: T, y: T) => U): U;
>baz : <T, U>(x: T, y: T, cb: (x: T, y: T) => U) => U
>T : T
>U : U
>x : T
>T : T
>y : T
>T : T
>cb : (x: T, y: T) => U
>x : T
>T : T
>y : T
>T : T
>U : U
>U : U
declare function g<T>(x: T, y: T): T;
>g : <T>(x: T, y: T) => T
>T : T
>x : T
>T : T
>y : T
>T : T
>T : T
declare function h<T, U>(x: T, y: U): T[] | U[];
>h : <T, U>(x: T, y: U) => T[] | U[]
>T : T
>U : U
>x : T
>T : T
>y : U
>U : U
>T : T
>U : U
var a: number;
>a : number
var a = bar(1, 1, g); // Should be number
>a : number
>bar(1, 1, g) : number
>bar : <T, U, V>(x: T, y: U, cb: (x: T, y: U) => V) => V
>g : <T>(x: T, y: T) => T
var a = baz(1, 1, g); // Should be number
>a : number
>baz(1, 1, g) : number
>baz : <T, U>(x: T, y: T, cb: (x: T, y: T) => U) => U
>g : <T>(x: T, y: T) => T
var b: number | string;
>b : string | number
var b = foo(g); // Should be number | string
>b : string | number
>foo(g) : string | number
>foo : <T>(cb: (x: number, y: string) => T) => T
>g : <T>(x: T, y: T) => T
var b = bar(1, "one", g); // Should be number | string
>b : string | number
>bar(1, "one", g) : string | number
>bar : <T, U, V>(x: T, y: U, cb: (x: T, y: U) => V) => V
>g : <T>(x: T, y: T) => T
var b = bar("one", 1, g); // Should be number | string
>b : string | number
>bar("one", 1, g) : string | number
>bar : <T, U, V>(x: T, y: U, cb: (x: T, y: U) => V) => V
>g : <T>(x: T, y: T) => T
var b = baz(b, b, g); // Should be number | string
>b : string | number
>baz(b, b, g) : string | number
>baz : <T, U>(x: T, y: T, cb: (x: T, y: T) => U) => U
>b : string | number
>b : string | number
>g : <T>(x: T, y: T) => T
var d: number[] | string[];
>d : number[] | string[]
var d = foo(h); // Should be number[] | string[]
>d : number[] | string[]
>foo(h) : number[] | string[]
>foo : <T>(cb: (x: number, y: string) => T) => T
>h : <T, U>(x: T, y: U) => T[] | U[]
var d = bar(1, "one", h); // Should be number[] | string[]
>d : number[] | string[]
>bar(1, "one", h) : number[] | string[]
>bar : <T, U, V>(x: T, y: U, cb: (x: T, y: U) => V) => V
>h : <T, U>(x: T, y: U) => T[] | U[]
var d = bar("one", 1, h); // Should be number[] | string[]
>d : number[] | string[]
>bar("one", 1, h) : number[] | string[]
>bar : <T, U, V>(x: T, y: U, cb: (x: T, y: U) => V) => V
>h : <T, U>(x: T, y: U) => T[] | U[]
var d = baz(d, d, g); // Should be number[] | string[]
>d : number[] | string[]
>baz(d, d, g) : number[] | string[]
>baz : <T, U>(x: T, y: T, cb: (x: T, y: T) => U) => U
>d : number[] | string[]
>d : number[] | string[]
>g : <T>(x: T, y: T) => T

View File

@@ -0,0 +1,548 @@
=== tests/cases/conformance/types/typeRelationships/bestCommonType/heterogeneousArrayLiterals.ts ===
// type of an array is the best common type of its elements (plus its contextual type if it exists)
var a = [1, '']; // {}[]
>a : (string | number)[]
>[1, ''] : (string | number)[]
var b = [1, null]; // number[]
>b : number[]
>[1, null] : number[]
var c = [1, '', null]; // {}[]
>c : (string | number)[]
>[1, '', null] : (string | number)[]
var d = [{}, 1]; // {}[]
>d : {}[]
>[{}, 1] : {}[]
>{} : {}
var e = [{}, Object]; // {}[]
>e : {}[]
>[{}, Object] : {}[]
>{} : {}
>Object : ObjectConstructor
var f = [[], [1]]; // number[][]
>f : number[][]
>[[], [1]] : number[][]
>[] : undefined[]
>[1] : number[]
var g = [[1], ['']]; // {}[]
>g : (number[] | string[])[]
>[[1], ['']] : (number[] | string[])[]
>[1] : number[]
>[''] : string[]
var h = [{ foo: 1, bar: '' }, { foo: 2 }]; // {foo: number}[]
>h : { foo: number; }[]
>[{ foo: 1, bar: '' }, { foo: 2 }] : { foo: number; }[]
>{ foo: 1, bar: '' } : { foo: number; bar: string; }
>foo : number
>bar : string
>{ foo: 2 } : { foo: number; }
>foo : number
var i = [{ foo: 1, bar: '' }, { foo: '' }]; // {}[]
>i : ({ foo: number; bar: string; } | { foo: string; })[]
>[{ foo: 1, bar: '' }, { foo: '' }] : ({ foo: number; bar: string; } | { foo: string; })[]
>{ foo: 1, bar: '' } : { foo: number; bar: string; }
>foo : number
>bar : string
>{ foo: '' } : { foo: string; }
>foo : string
var j = [() => 1, () => '']; // {}[]
>j : ((() => number) | (() => string))[]
>[() => 1, () => ''] : ((() => number) | (() => string))[]
>() => 1 : () => number
>() => '' : () => string
var k = [() => 1, () => 1]; // { (): number }[]
>k : (() => number)[]
>[() => 1, () => 1] : (() => number)[]
>() => 1 : () => number
>() => 1 : () => number
var l = [() => 1, () => null]; // { (): any }[]
>l : (() => any)[]
>[() => 1, () => null] : (() => any)[]
>() => 1 : () => number
>() => null : () => any
var m = [() => 1, () => '', () => null]; // { (): any }[]
>m : (() => any)[]
>[() => 1, () => '', () => null] : (() => any)[]
>() => 1 : () => number
>() => '' : () => string
>() => null : () => any
var n = [[() => 1], [() => '']]; // {}[]
>n : ((() => number)[] | (() => string)[])[]
>[[() => 1], [() => '']] : ((() => number)[] | (() => string)[])[]
>[() => 1] : (() => number)[]
>() => 1 : () => number
>[() => ''] : (() => string)[]
>() => '' : () => string
class Base { foo: string; }
>Base : Base
>foo : string
class Derived extends Base { bar: string; }
>Derived : Derived
>Base : Base
>bar : string
class Derived2 extends Base { baz: string; }
>Derived2 : Derived2
>Base : Base
>baz : string
var base: Base;
>base : Base
>Base : Base
var derived: Derived;
>derived : Derived
>Derived : Derived
var derived2: Derived2;
>derived2 : Derived2
>Derived2 : Derived2
module Derived {
>Derived : typeof Derived
var h = [{ foo: base, basear: derived }, { foo: base }]; // {foo: Base}[]
>h : { foo: Base; }[]
>[{ foo: base, basear: derived }, { foo: base }] : { foo: Base; }[]
>{ foo: base, basear: derived } : { foo: Base; basear: Derived; }
>foo : Base
>base : Base
>basear : Derived
>derived : Derived
>{ foo: base } : { foo: Base; }
>foo : Base
>base : Base
var i = [{ foo: base, basear: derived }, { foo: derived }]; // {foo: Derived}[]
>i : ({ foo: Base; basear: Derived; } | { foo: Derived; })[]
>[{ foo: base, basear: derived }, { foo: derived }] : ({ foo: Base; basear: Derived; } | { foo: Derived; })[]
>{ foo: base, basear: derived } : { foo: Base; basear: Derived; }
>foo : Base
>base : Base
>basear : Derived
>derived : Derived
>{ foo: derived } : { foo: Derived; }
>foo : Derived
>derived : Derived
var j = [() => base, () => derived]; // { {}: Base }
>j : (() => Base)[]
>[() => base, () => derived] : (() => Base)[]
>() => base : () => Base
>base : Base
>() => derived : () => Derived
>derived : Derived
var k = [() => base, () => 1]; // {}[]~
>k : ((() => Base) | (() => number))[]
>[() => base, () => 1] : ((() => Base) | (() => number))[]
>() => base : () => Base
>base : Base
>() => 1 : () => number
var l = [() => base, () => null]; // { (): any }[]
>l : (() => any)[]
>[() => base, () => null] : (() => any)[]
>() => base : () => Base
>base : Base
>() => null : () => any
var m = [() => base, () => derived, () => null]; // { (): any }[]
>m : (() => any)[]
>[() => base, () => derived, () => null] : (() => any)[]
>() => base : () => Base
>base : Base
>() => derived : () => Derived
>derived : Derived
>() => null : () => any
var n = [[() => base], [() => derived]]; // { (): Base }[]
>n : (() => Base)[][]
>[[() => base], [() => derived]] : (() => Base)[][]
>[() => base] : (() => Base)[]
>() => base : () => Base
>base : Base
>[() => derived] : (() => Derived)[]
>() => derived : () => Derived
>derived : Derived
var o = [derived, derived2]; // {}[]
>o : (Derived | Derived2)[]
>[derived, derived2] : (Derived | Derived2)[]
>derived : Derived
>derived2 : Derived2
var p = [derived, derived2, base]; // Base[]
>p : Base[]
>[derived, derived2, base] : Base[]
>derived : Derived
>derived2 : Derived2
>base : Base
var q = [[() => derived2], [() => derived]]; // {}[]
>q : ((() => Derived2)[] | (() => Derived)[])[]
>[[() => derived2], [() => derived]] : ((() => Derived2)[] | (() => Derived)[])[]
>[() => derived2] : (() => Derived2)[]
>() => derived2 : () => Derived2
>derived2 : Derived2
>[() => derived] : (() => Derived)[]
>() => derived : () => Derived
>derived : Derived
}
module WithContextualType {
>WithContextualType : typeof WithContextualType
// no errors
var a: Base[] = [derived, derived2];
>a : Base[]
>Base : Base
>[derived, derived2] : (Derived | Derived2)[]
>derived : Derived
>derived2 : Derived2
var b: Derived[] = [null];
>b : Derived[]
>Derived : Derived
>[null] : null[]
var c: Derived[] = [];
>c : Derived[]
>Derived : Derived
>[] : undefined[]
var d: { (): Base }[] = [() => derived, () => derived2];
>d : (() => Base)[]
>Base : Base
>[() => derived, () => derived2] : ((() => Derived) | (() => Derived2))[]
>() => derived : () => Derived
>derived : Derived
>() => derived2 : () => Derived2
>derived2 : Derived2
}
function foo<T, U>(t: T, u: U) {
>foo : <T, U>(t: T, u: U) => void
>T : T
>U : U
>t : T
>T : T
>u : U
>U : U
var a = [t, t]; // T[]
>a : T[]
>[t, t] : T[]
>t : T
>t : T
var b = [t, null]; // T[]
>b : T[]
>[t, null] : T[]
>t : T
var c = [t, u]; // {}[]
>c : (T | U)[]
>[t, u] : (T | U)[]
>t : T
>u : U
var d = [t, 1]; // {}[]
>d : (number | T)[]
>[t, 1] : (number | T)[]
>t : T
var e = [() => t, () => u]; // {}[]
>e : ((() => T) | (() => U))[]
>[() => t, () => u] : ((() => T) | (() => U))[]
>() => t : () => T
>t : T
>() => u : () => U
>u : U
var f = [() => t, () => u, () => null]; // { (): any }[]
>f : (() => any)[]
>[() => t, () => u, () => null] : (() => any)[]
>() => t : () => T
>t : T
>() => u : () => U
>u : U
>() => null : () => any
}
function foo2<T extends Base, U extends Derived>(t: T, u: U) {
>foo2 : <T extends Base, U extends Derived>(t: T, u: U) => void
>T : T
>Base : Base
>U : U
>Derived : Derived
>t : T
>T : T
>u : U
>U : U
var a = [t, t]; // T[]
>a : T[]
>[t, t] : T[]
>t : T
>t : T
var b = [t, null]; // T[]
>b : T[]
>[t, null] : T[]
>t : T
var c = [t, u]; // {}[]
>c : (T | U)[]
>[t, u] : (T | U)[]
>t : T
>u : U
var d = [t, 1]; // {}[]
>d : (number | T)[]
>[t, 1] : (number | T)[]
>t : T
var e = [() => t, () => u]; // {}[]
>e : ((() => T) | (() => U))[]
>[() => t, () => u] : ((() => T) | (() => U))[]
>() => t : () => T
>t : T
>() => u : () => U
>u : U
var f = [() => t, () => u, () => null]; // { (): any }[]
>f : (() => any)[]
>[() => t, () => u, () => null] : (() => any)[]
>() => t : () => T
>t : T
>() => u : () => U
>u : U
>() => null : () => any
var g = [t, base]; // Base[]
>g : Base[]
>[t, base] : Base[]
>t : T
>base : Base
var h = [t, derived]; // Derived[]
>h : (Derived | T)[]
>[t, derived] : (Derived | T)[]
>t : T
>derived : Derived
var i = [u, base]; // Base[]
>i : Base[]
>[u, base] : Base[]
>u : U
>base : Base
var j = [u, derived]; // Derived[]
>j : Derived[]
>[u, derived] : Derived[]
>u : U
>derived : Derived
}
function foo3<T extends Derived, U extends Derived>(t: T, u: U) {
>foo3 : <T extends Derived, U extends Derived>(t: T, u: U) => void
>T : T
>Derived : Derived
>U : U
>Derived : Derived
>t : T
>T : T
>u : U
>U : U
var a = [t, t]; // T[]
>a : T[]
>[t, t] : T[]
>t : T
>t : T
var b = [t, null]; // T[]
>b : T[]
>[t, null] : T[]
>t : T
var c = [t, u]; // {}[]
>c : (T | U)[]
>[t, u] : (T | U)[]
>t : T
>u : U
var d = [t, 1]; // {}[]
>d : (number | T)[]
>[t, 1] : (number | T)[]
>t : T
var e = [() => t, () => u]; // {}[]
>e : ((() => T) | (() => U))[]
>[() => t, () => u] : ((() => T) | (() => U))[]
>() => t : () => T
>t : T
>() => u : () => U
>u : U
var f = [() => t, () => u, () => null]; // { (): any }[]
>f : (() => any)[]
>[() => t, () => u, () => null] : (() => any)[]
>() => t : () => T
>t : T
>() => u : () => U
>u : U
>() => null : () => any
var g = [t, base]; // Base[]
>g : Base[]
>[t, base] : Base[]
>t : T
>base : Base
var h = [t, derived]; // Derived[]
>h : Derived[]
>[t, derived] : Derived[]
>t : T
>derived : Derived
var i = [u, base]; // Base[]
>i : Base[]
>[u, base] : Base[]
>u : U
>base : Base
var j = [u, derived]; // Derived[]
>j : Derived[]
>[u, derived] : Derived[]
>u : U
>derived : Derived
}
function foo4<T extends Base, U extends Base>(t: T, u: U) {
>foo4 : <T extends Base, U extends Base>(t: T, u: U) => void
>T : T
>Base : Base
>U : U
>Base : Base
>t : T
>T : T
>u : U
>U : U
var a = [t, t]; // T[]
>a : T[]
>[t, t] : T[]
>t : T
>t : T
var b = [t, null]; // T[]
>b : T[]
>[t, null] : T[]
>t : T
var c = [t, u]; // BUG 821629
>c : (T | U)[]
>[t, u] : (T | U)[]
>t : T
>u : U
var d = [t, 1]; // {}[]
>d : (number | T)[]
>[t, 1] : (number | T)[]
>t : T
var e = [() => t, () => u]; // {}[]
>e : ((() => T) | (() => U))[]
>[() => t, () => u] : ((() => T) | (() => U))[]
>() => t : () => T
>t : T
>() => u : () => U
>u : U
var f = [() => t, () => u, () => null]; // { (): any }[]
>f : (() => any)[]
>[() => t, () => u, () => null] : (() => any)[]
>() => t : () => T
>t : T
>() => u : () => U
>u : U
>() => null : () => any
var g = [t, base]; // Base[]
>g : Base[]
>[t, base] : Base[]
>t : T
>base : Base
var h = [t, derived]; // Derived[]
>h : (Derived | T)[]
>[t, derived] : (Derived | T)[]
>t : T
>derived : Derived
var i = [u, base]; // Base[]
>i : Base[]
>[u, base] : Base[]
>u : U
>base : Base
var j = [u, derived]; // Derived[]
>j : (Derived | U)[]
>[u, derived] : (Derived | U)[]
>u : U
>derived : Derived
var k: Base[] = [t, u];
>k : Base[]
>Base : Base
>[t, u] : (T | U)[]
>t : T
>u : U
}
//function foo3<T extends U, U extends Derived>(t: T, u: U) {
// var a = [t, t]; // T[]
// var b = [t, null]; // T[]
// var c = [t, u]; // {}[]
// var d = [t, 1]; // {}[]
// var e = [() => t, () => u]; // {}[]
// var f = [() => t, () => u, () => null]; // { (): any }[]
// var g = [t, base]; // Base[]
// var h = [t, derived]; // Derived[]
// var i = [u, base]; // Base[]
// var j = [u, derived]; // Derived[]
//}
//function foo4<T extends U, U extends Base>(t: T, u: U) {
// var a = [t, t]; // T[]
// var b = [t, null]; // T[]
// var c = [t, u]; // BUG 821629
// var d = [t, 1]; // {}[]
// var e = [() => t, () => u]; // {}[]
// var f = [() => t, () => u, () => null]; // { (): any }[]
// var g = [t, base]; // Base[]
// var h = [t, derived]; // Derived[]
// var i = [u, base]; // Base[]
// var j = [u, derived]; // Derived[]
// var k: Base[] = [t, u];
//}

View File

@@ -0,0 +1,618 @@
=== tests/cases/conformance/expressions/binaryOperators/logicalOrOperator/logicalOrOperatorWithEveryType.ts ===
// The || operator permits the operands to be of any type.
// If the || expression is not contextually typed, the right operand is contextually typed
// by the type of the left operand and the result is of the best common type of the two
// operand types.
enum E { a, b, c }
>E : E
>a : E
>b : E
>c : E
var a1: any;
>a1 : any
var a2: boolean;
>a2 : boolean
var a3: number
>a3 : number
var a4: string;
>a4 : string
var a5: void;
>a5 : void
var a6: E;
>a6 : E
>E : E
var a7: {a: string};
>a7 : { a: string; }
>a : string
var a8: string[];
>a8 : string[]
var ra1 = a1 || a1; // any || any is any
>ra1 : any
>a1 || a1 : any
>a1 : any
>a1 : any
var ra2 = a2 || a1; // boolean || any is any
>ra2 : any
>a2 || a1 : any
>a2 : boolean
>a1 : any
var ra3 = a3 || a1; // number || any is any
>ra3 : any
>a3 || a1 : any
>a3 : number
>a1 : any
var ra4 = a4 || a1; // string || any is any
>ra4 : any
>a4 || a1 : any
>a4 : string
>a1 : any
var ra5 = a5 || a1; // void || any is any
>ra5 : any
>a5 || a1 : any
>a5 : void
>a1 : any
var ra6 = a6 || a1; // enum || any is any
>ra6 : any
>a6 || a1 : any
>a6 : E
>a1 : any
var ra7 = a7 || a1; // object || any is any
>ra7 : any
>a7 || a1 : any
>a7 : { a: string; }
>a1 : any
var ra8 = a8 || a1; // array || any is any
>ra8 : any
>a8 || a1 : any
>a8 : string[]
>a1 : any
var ra9 = null || a1; // null || any is any
>ra9 : any
>null || a1 : any
>a1 : any
var ra10 = undefined || a1; // undefined || any is any
>ra10 : any
>undefined || a1 : any
>undefined : undefined
>a1 : any
var rb1 = a1 || a2; // any || boolean is any
>rb1 : any
>a1 || a2 : any
>a1 : any
>a2 : boolean
var rb2 = a2 || a2; // boolean || boolean is boolean
>rb2 : boolean
>a2 || a2 : boolean
>a2 : boolean
>a2 : boolean
var rb3 = a3 || a2; // number || boolean is number | boolean
>rb3 : number | boolean
>a3 || a2 : number | boolean
>a3 : number
>a2 : boolean
var rb4 = a4 || a2; // string || boolean is string | boolean
>rb4 : string | boolean
>a4 || a2 : string | boolean
>a4 : string
>a2 : boolean
var rb5 = a5 || a2; // void || boolean is void | boolean
>rb5 : boolean | void
>a5 || a2 : boolean | void
>a5 : void
>a2 : boolean
var rb6 = a6 || a2; // enum || boolean is E | boolean
>rb6 : boolean | E
>a6 || a2 : boolean | E
>a6 : E
>a2 : boolean
var rb7 = a7 || a2; // object || boolean is object | boolean
>rb7 : boolean | { a: string; }
>a7 || a2 : boolean | { a: string; }
>a7 : { a: string; }
>a2 : boolean
var rb8 = a8 || a2; // array || boolean is array | boolean
>rb8 : boolean | string[]
>a8 || a2 : boolean | string[]
>a8 : string[]
>a2 : boolean
var rb9 = null || a2; // null || boolean is boolean
>rb9 : boolean
>null || a2 : boolean
>a2 : boolean
var rb10= undefined || a2; // undefined || boolean is boolean
>rb10 : boolean
>undefined || a2 : boolean
>undefined : undefined
>a2 : boolean
var rc1 = a1 || a3; // any || number is any
>rc1 : any
>a1 || a3 : any
>a1 : any
>a3 : number
var rc2 = a2 || a3; // boolean || number is boolean | number
>rc2 : number | boolean
>a2 || a3 : number | boolean
>a2 : boolean
>a3 : number
var rc3 = a3 || a3; // number || number is number
>rc3 : number
>a3 || a3 : number
>a3 : number
>a3 : number
var rc4 = a4 || a3; // string || number is string | number
>rc4 : string | number
>a4 || a3 : string | number
>a4 : string
>a3 : number
var rc5 = a5 || a3; // void || number is void | number
>rc5 : number | void
>a5 || a3 : number | void
>a5 : void
>a3 : number
var rc6 = a6 || a3; // enum || number is number
>rc6 : number
>a6 || a3 : number
>a6 : E
>a3 : number
var rc7 = a7 || a3; // object || number is object | number
>rc7 : number | { a: string; }
>a7 || a3 : number | { a: string; }
>a7 : { a: string; }
>a3 : number
var rc8 = a8 || a3; // array || number is array | number
>rc8 : number | string[]
>a8 || a3 : number | string[]
>a8 : string[]
>a3 : number
var rc9 = null || a3; // null || number is number
>rc9 : number
>null || a3 : number
>a3 : number
var rc10 = undefined || a3; // undefined || number is number
>rc10 : number
>undefined || a3 : number
>undefined : undefined
>a3 : number
var rd1 = a1 || a4; // any || string is any
>rd1 : any
>a1 || a4 : any
>a1 : any
>a4 : string
var rd2 = a2 || a4; // boolean || string is boolean | string
>rd2 : string | boolean
>a2 || a4 : string | boolean
>a2 : boolean
>a4 : string
var rd3 = a3 || a4; // number || string is number | string
>rd3 : string | number
>a3 || a4 : string | number
>a3 : number
>a4 : string
var rd4 = a4 || a4; // string || string is string
>rd4 : string
>a4 || a4 : string
>a4 : string
>a4 : string
var rd5 = a5 || a4; // void || string is void | string
>rd5 : string | void
>a5 || a4 : string | void
>a5 : void
>a4 : string
var rd6 = a6 || a4; // enum || string is enum | string
>rd6 : string | E
>a6 || a4 : string | E
>a6 : E
>a4 : string
var rd7 = a7 || a4; // object || string is object | string
>rd7 : string | { a: string; }
>a7 || a4 : string | { a: string; }
>a7 : { a: string; }
>a4 : string
var rd8 = a8 || a4; // array || string is array | string
>rd8 : string | string[]
>a8 || a4 : string | string[]
>a8 : string[]
>a4 : string
var rd9 = null || a4; // null || string is string
>rd9 : string
>null || a4 : string
>a4 : string
var rd10 = undefined || a4; // undefined || string is string
>rd10 : string
>undefined || a4 : string
>undefined : undefined
>a4 : string
var re1 = a1 || a5; // any || void is any
>re1 : any
>a1 || a5 : any
>a1 : any
>a5 : void
var re2 = a2 || a5; // boolean || void is boolean | void
>re2 : boolean | void
>a2 || a5 : boolean | void
>a2 : boolean
>a5 : void
var re3 = a3 || a5; // number || void is number | void
>re3 : number | void
>a3 || a5 : number | void
>a3 : number
>a5 : void
var re4 = a4 || a5; // string || void is string | void
>re4 : string | void
>a4 || a5 : string | void
>a4 : string
>a5 : void
var re5 = a5 || a5; // void || void is void
>re5 : void
>a5 || a5 : void
>a5 : void
>a5 : void
var re6 = a6 || a5; // enum || void is enum | void
>re6 : void | E
>a6 || a5 : void | E
>a6 : E
>a5 : void
var re7 = a7 || a5; // object || void is object | void
>re7 : void | { a: string; }
>a7 || a5 : void | { a: string; }
>a7 : { a: string; }
>a5 : void
var re8 = a8 || a5; // array || void is array | void
>re8 : void | string[]
>a8 || a5 : void | string[]
>a8 : string[]
>a5 : void
var re9 = null || a5; // null || void is void
>re9 : void
>null || a5 : void
>a5 : void
var re10 = undefined || a5; // undefined || void is void
>re10 : void
>undefined || a5 : void
>undefined : undefined
>a5 : void
var rg1 = a1 || a6; // any || enum is any
>rg1 : any
>a1 || a6 : any
>a1 : any
>a6 : E
var rg2 = a2 || a6; // boolean || enum is boolean | enum
>rg2 : boolean | E
>a2 || a6 : boolean | E
>a2 : boolean
>a6 : E
var rg3 = a3 || a6; // number || enum is number
>rg3 : number
>a3 || a6 : number
>a3 : number
>a6 : E
var rg4 = a4 || a6; // string || enum is string | enum
>rg4 : string | E
>a4 || a6 : string | E
>a4 : string
>a6 : E
var rg5 = a5 || a6; // void || enum is void | enum
>rg5 : void | E
>a5 || a6 : void | E
>a5 : void
>a6 : E
var rg6 = a6 || a6; // enum || enum is E
>rg6 : E
>a6 || a6 : E
>a6 : E
>a6 : E
var rg7 = a7 || a6; // object || enum is object | enum
>rg7 : E | { a: string; }
>a7 || a6 : E | { a: string; }
>a7 : { a: string; }
>a6 : E
var rg8 = a8 || a6; // array || enum is array | enum
>rg8 : E | string[]
>a8 || a6 : E | string[]
>a8 : string[]
>a6 : E
var rg9 = null || a6; // null || enum is E
>rg9 : E
>null || a6 : E
>a6 : E
var rg10 = undefined || a6; // undefined || enum is E
>rg10 : E
>undefined || a6 : E
>undefined : undefined
>a6 : E
var rh1 = a1 || a7; // any || object is any
>rh1 : any
>a1 || a7 : any
>a1 : any
>a7 : { a: string; }
var rh2 = a2 || a7; // boolean || object is boolean | object
>rh2 : boolean | { a: string; }
>a2 || a7 : boolean | { a: string; }
>a2 : boolean
>a7 : { a: string; }
var rh3 = a3 || a7; // number || object is number | object
>rh3 : number | { a: string; }
>a3 || a7 : number | { a: string; }
>a3 : number
>a7 : { a: string; }
var rh4 = a4 || a7; // string || object is string | object
>rh4 : string | { a: string; }
>a4 || a7 : string | { a: string; }
>a4 : string
>a7 : { a: string; }
var rh5 = a5 || a7; // void || object is void | object
>rh5 : void | { a: string; }
>a5 || a7 : void | { a: string; }
>a5 : void
>a7 : { a: string; }
var rh6 = a6 || a7; // enum || object is enum | object
>rh6 : E | { a: string; }
>a6 || a7 : E | { a: string; }
>a6 : E
>a7 : { a: string; }
var rh7 = a7 || a7; // object || object is object
>rh7 : { a: string; }
>a7 || a7 : { a: string; }
>a7 : { a: string; }
>a7 : { a: string; }
var rh8 = a8 || a7; // array || object is array | object
>rh8 : { a: string; } | string[]
>a8 || a7 : { a: string; } | string[]
>a8 : string[]
>a7 : { a: string; }
var rh9 = null || a7; // null || object is object
>rh9 : { a: string; }
>null || a7 : { a: string; }
>a7 : { a: string; }
var rh10 = undefined || a7; // undefined || object is object
>rh10 : { a: string; }
>undefined || a7 : { a: string; }
>undefined : undefined
>a7 : { a: string; }
var ri1 = a1 || a8; // any || array is any
>ri1 : any
>a1 || a8 : any
>a1 : any
>a8 : string[]
var ri2 = a2 || a8; // boolean || array is boolean | array
>ri2 : boolean | string[]
>a2 || a8 : boolean | string[]
>a2 : boolean
>a8 : string[]
var ri3 = a3 || a8; // number || array is number | array
>ri3 : number | string[]
>a3 || a8 : number | string[]
>a3 : number
>a8 : string[]
var ri4 = a4 || a8; // string || array is string | array
>ri4 : string | string[]
>a4 || a8 : string | string[]
>a4 : string
>a8 : string[]
var ri5 = a5 || a8; // void || array is void | array
>ri5 : void | string[]
>a5 || a8 : void | string[]
>a5 : void
>a8 : string[]
var ri6 = a6 || a8; // enum || array is enum | array
>ri6 : E | string[]
>a6 || a8 : E | string[]
>a6 : E
>a8 : string[]
var ri7 = a7 || a8; // object || array is object | array
>ri7 : { a: string; } | string[]
>a7 || a8 : { a: string; } | string[]
>a7 : { a: string; }
>a8 : string[]
var ri8 = a8 || a8; // array || array is array
>ri8 : string[]
>a8 || a8 : string[]
>a8 : string[]
>a8 : string[]
var ri9 = null || a8; // null || array is array
>ri9 : string[]
>null || a8 : string[]
>a8 : string[]
var ri10 = undefined || a8; // undefined || array is array
>ri10 : string[]
>undefined || a8 : string[]
>undefined : undefined
>a8 : string[]
var rj1 = a1 || null; // any || null is any
>rj1 : any
>a1 || null : any
>a1 : any
var rj2 = a2 || null; // boolean || null is boolean
>rj2 : boolean
>a2 || null : boolean
>a2 : boolean
var rj3 = a3 || null; // number || null is number
>rj3 : number
>a3 || null : number
>a3 : number
var rj4 = a4 || null; // string || null is string
>rj4 : string
>a4 || null : string
>a4 : string
var rj5 = a5 || null; // void || null is void
>rj5 : void
>a5 || null : void
>a5 : void
var rj6 = a6 || null; // enum || null is E
>rj6 : E
>a6 || null : E
>a6 : E
var rj7 = a7 || null; // object || null is object
>rj7 : { a: string; }
>a7 || null : { a: string; }
>a7 : { a: string; }
var rj8 = a8 || null; // array || null is array
>rj8 : string[]
>a8 || null : string[]
>a8 : string[]
var rj9 = null || null; // null || null is any
>rj9 : any
>null || null : null
var rj10 = undefined || null; // undefined || null is any
>rj10 : any
>undefined || null : null
>undefined : undefined
var rf1 = a1 || undefined; // any || undefined is any
>rf1 : any
>a1 || undefined : any
>a1 : any
>undefined : undefined
var rf2 = a2 || undefined; // boolean || undefined is boolean
>rf2 : boolean
>a2 || undefined : boolean
>a2 : boolean
>undefined : undefined
var rf3 = a3 || undefined; // number || undefined is number
>rf3 : number
>a3 || undefined : number
>a3 : number
>undefined : undefined
var rf4 = a4 || undefined; // string || undefined is string
>rf4 : string
>a4 || undefined : string
>a4 : string
>undefined : undefined
var rf5 = a5 || undefined; // void || undefined is void
>rf5 : void
>a5 || undefined : void
>a5 : void
>undefined : undefined
var rf6 = a6 || undefined; // enum || undefined is E
>rf6 : E
>a6 || undefined : E
>a6 : E
>undefined : undefined
var rf7 = a7 || undefined; // object || undefined is object
>rf7 : { a: string; }
>a7 || undefined : { a: string; }
>a7 : { a: string; }
>undefined : undefined
var rf8 = a8 || undefined; // array || undefined is array
>rf8 : string[]
>a8 || undefined : string[]
>a8 : string[]
>undefined : undefined
var rf9 = null || undefined; // null || undefined is any
>rf9 : any
>null || undefined : null
>undefined : undefined
var rf10 = undefined || undefined; // undefined || undefined is any
>rf10 : any
>undefined || undefined : undefined
>undefined : undefined
>undefined : undefined

View File

@@ -0,0 +1,356 @@
=== 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
? 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
? (x = 10 && x)// string | number
>(x = 10 && x) : string | number
>x = 10 && x : string | number
>x : string | number
>10 && x : string | 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
? (x = "Hello" && x) // string | number
>(x = "Hello" && x) : string | number
>x = "Hello" && x : string | number
>x : string | number
>"Hello" && x : string | number
>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
? 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
>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
? 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
>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
? (x = 10 && x) // string | number
>(x = 10 && x) : string | number
>x = 10 && x : string | number
>x : string | number
>10 && 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
>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
? x === "hello" // string
>x === "hello" : boolean
>x : string
: typeof x === "boolean"
>typeof x === "boolean" ? x // boolean : x == 10 : boolean
>typeof x === "boolean" : boolean
>typeof x : string
>x : number | boolean
? x // boolean
>x : boolean
: x == 10; // number
>x == 10 : boolean
>x : 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
? x === "hello"
>x === "hello" : boolean
>x : 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
? x // boolean
>x : boolean
: x == 10)); // number
>x == 10 : boolean
>x : number
}
function foo9(x: number | string) {
>foo9 : (x: string | number) => boolean
>x : string | number
var y = 10;
>y : 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
? ((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
: x === 10; // number
>x === 10 : boolean
>x : 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
? 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
&& 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
? 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
&& (x = 10) // assignment to x
>(x = 10) : number
>x = 10 : number
>x : string | number | boolean
&& 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
? (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
>x.toString().length : number
>x.toString() : string
>x.toString : (radix?: number) => string
>x : string | number | boolean
>toString : (radix?: number) => 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
&& x); // x is number
>x : number
}