Merge branch 'master' into relativePathReferenceResolution

This commit is contained in:
Sheetal Nandi
2014-11-19 13:11:17 -08:00
262 changed files with 22510 additions and 22551 deletions
+9
View File
@@ -0,0 +1,9 @@
//@module: amd
///<amd-module name='NamedModule'/>
class Foo {
x: number;
constructor() {
this.x = 5;
}
}
export = Foo;
+10
View File
@@ -0,0 +1,10 @@
//@module: amd
///<amd-module name='FirstModuleName'/>
///<amd-module name='SecondModuleName'/>
class Foo {
x: number;
constructor() {
this.x = 5;
}
}
export = Foo;
@@ -0,0 +1,15 @@
// @module: commonjs
// @Filename: elidingImportNames_test.ts
import a = require('elidingImportNames_main'); // alias used in typeof
var b = a;
var x: typeof a;
import a2 = require('elidingImportNames_main1'); // alias not used in typeof
var b2 = a2;
// @Filename: elidingImportNames_main.ts
export var main = 10;
// @Filename: elidingImportNames_main1.ts
export var main = 10;
+5
View File
@@ -0,0 +1,5 @@
// @noemitonerror: true
// @sourcemap: true
// @declaration: true
var x: number = "";
@@ -0,0 +1,14 @@
// Before fix this would take an exceeding long time to complete (#1170)
interface Observable<T> {
// This member can't be of type T, Property<T>, or Observable<anything but T>
needThisOne: Observable<T>;
// Add more to make it slower
expo1: Property<T[]>; // 0.31 seconds in check
expo2: Property<T[]>; // 3.11 seconds
expo3: Property<T[]>; // 82.28 seconds
}
interface Property<T> extends Observable<T> { }
var p: Observable<{}>;
var stuck: Property<number> = p;
@@ -0,0 +1,30 @@
// Before fix this would cause compiler to hang (#1170)
declare module Bacon {
interface Event<T> {
}
interface Error<T> extends Event<T> {
}
interface Observable<T> {
zip<U, V>(other: EventStream<U>, f: (a: T, b: U) => V): EventStream<V>;
slidingWindow(max: number, min?: number): Property<T[]>;
log(): Observable<T>;
combine<U, V>(other: Observable<U>, f: (a: T, b: U) => V): Property<V>;
withStateMachine<U, V>(initState: U, f: (state: U, event: Event<T>) => StateValue<U, V>): EventStream<V>;
decode(mapping: Object): Property<any>;
awaiting<U>(other: Observable<U>): Property<boolean>;
endOnError(f?: (value: T) => boolean): Observable<T>;
withHandler(f: (event: Event<T>) => any): Observable<T>;
name(name: string): Observable<T>;
withDescription(...args: any[]): Observable<T>;
}
interface Property<T> extends Observable<T> {
}
interface EventStream<T> extends Observable<T> {
}
interface Bus<T> extends EventStream<T> {
}
var Bus: new <T>() => Bus<T>;
}
var stuck: Bacon.Bus<number> = new Bacon.Bus();
@@ -0,0 +1,11 @@
// @target: es5
class TemplateStringsArray {
}
function f(x: TemplateStringsArray, y: number, z: number) {
}
f({}, 10, 10);
f `abcdef${ 1234 }${ 5678 }ghijkl`;
@@ -0,0 +1,8 @@
// @target: es5
function f(x: TemplateStringsArray, y: number, z: number) {
}
f({}, 10, 10);
f `abcdef${ 1234 }${ 5678 }ghijkl`;
@@ -0,0 +1,11 @@
// @target: es6
class TemplateStringsArray {
}
function f(x: TemplateStringsArray, y: number, z: number) {
}
f({}, 10, 10);
f `abcdef${ 1234 }${ 5678 }ghijkl`;
@@ -0,0 +1,20 @@
// @target: es5
var a, b, c;
var x1 = {
a
};
var x2 = {
a,
}
var x3 = {
a: 0,
b,
c,
d() { },
x3,
parent: x3
};
@@ -0,0 +1,13 @@
var id: number = 10000;
var name: string = "my name";
var person: { name: string; id: number } = { name, id };
function foo( obj:{ name: string }): void { };
function bar(name: string, id: number) { return { name, id }; }
function bar1(name: string, id: number) { return { name }; }
function baz(name: string, id: number): { name: string; id: number } { return { name, id }; }
foo(person);
var person1 = bar("Hello", 5);
var person2: { name: string } = bar("Hello", 5);
var person3: { name: string; id:number } = bar("Hello", 5);
@@ -0,0 +1,14 @@
// @target: es6
var id: number = 10000;
var name: string = "my name";
var person: { name: string; id: number } = { name, id };
function foo(obj: { name: string }): void { };
function bar(name: string, id: number) { return { name, id }; }
function bar1(name: string, id: number) { return { name }; }
function baz(name: string, id: number): { name: string; id: number } { return { name, id }; }
foo(person);
var person1 = bar("Hello", 5);
var person2: { name: string } = bar("Hello", 5);
var person3: { name: string; id: number } = bar("Hello", 5);
@@ -0,0 +1,9 @@
var id: number = 10000;
var name: string = "my name";
var person: { b: string; id: number } = { name, id }; // error
var person1: { name, id }; // error: can't use short-hand property assignment in type position
function foo(name: string, id: number): { id: string, name: number } { return { name, id }; } // error
function bar(obj: { name: string; id: boolean }) { }
bar({ name, id }); // error
@@ -0,0 +1,8 @@
var id: number = 10000;
var name: string = "my name";
var person: { b: string; id: number } = { name, id }; // error
function bar(name: string, id: number): { name: number, id: string } { return { name, id }; } // error
function foo(name: string, id: number): { name: string, id: number } { return { name, id }; } // error
var person1: { name, id }; // error : Can't use shorthand in the type position
var person2: { name: string, id: number } = bar("hello", 5);
@@ -0,0 +1,20 @@
// @target: es6
var a, b, c;
var x1 = {
a
};
var x2 = {
a,
}
var x3 = {
a: 0,
b,
c,
d() { },
x3,
parent: x3
};
@@ -0,0 +1,4 @@
var x = {
x, // OK
undefinedVariable // Error
}
@@ -0,0 +1,20 @@
// errors
var y = {
"stringLiteral",
42,
get e,
set f,
this,
super,
var,
class,
typeof
};
var x = {
a.b,
a["ss"],
a[1],
};
var v = { class }; // error
@@ -0,0 +1,14 @@
// module export
var x = "Foo";
module m {
export var x;
}
module n {
var z = 10000;
export var y = {
m.x // error
};
}
m.y.x;
@@ -0,0 +1,10 @@
var id: number = 10000;
var name: string = "my name";
var person = { name, id };
function foo(p: { name: string; id: number }) { }
foo(person);
var obj = { name: name, id: id };
@@ -0,0 +1,7 @@
var id: number = 10000;
var name: string = "my name";
var person = { name, id };
function foo(p: { a: string; id: number }) { }
foo(person); // error
@@ -0,0 +1,13 @@
// module export
module m {
export var x;
}
module m {
var z = x;
var y = {
a: x,
x
};
}
@@ -0,0 +1,13 @@
// @target: es6
module m {
export var x;
}
module m {
var z = x;
var y = {
a: x,
x
};
}
@@ -0,0 +1,46 @@
var str: string;
var bool: boolean;
var num: number;
var strOrNum: string | number;
var strOrNumOrBool: string | number | boolean;
var numOrBool: number | boolean;
class C { private p; }
var c: C;
var cOrBool: C| boolean;
var strOrNumOrBoolOrC: string | number | boolean | C;
// A type guard of the form expr1 && expr2
// - when true, narrows the type of x by expr1 when true and then by expr2 when true, or
// - when false, narrows the type of x to T1 | T2, where T1 is the type of x narrowed by expr1 when
// false, and T2 is the type of x narrowed by expr1 when true and then by expr2 when false.
// (typeguard1 && typeguard2)
if (typeof strOrNumOrBool !== "string" && typeof strOrNumOrBool !== "number") {
bool = strOrNumOrBool; // boolean
}
else {
strOrNum = strOrNumOrBool; // string | number
}
// (typeguard1 && typeguard2 && typeguard3)
if (typeof strOrNumOrBoolOrC !== "string" && typeof strOrNumOrBoolOrC !== "number" && typeof strOrNumOrBoolOrC !== "boolean") {
c = strOrNumOrBoolOrC; // C
}
else {
strOrNumOrBool = strOrNumOrBoolOrC; // string | number | boolean
}
// (typeguard1 && typeguard2 && typeguard11(onAnotherType))
if (typeof strOrNumOrBoolOrC !== "string" && typeof strOrNumOrBoolOrC !== "number" && typeof strOrNumOrBool === "boolean") {
cOrBool = strOrNumOrBoolOrC; // C | boolean
bool = strOrNumOrBool; // boolean
}
else {
var r1: string | number | boolean | C = strOrNumOrBoolOrC; // string | number | boolean | C
var r2: string | number | boolean = strOrNumOrBool;
}
// (typeguard1) && simpleExpr
if (typeof strOrNumOrBool !== "string" && numOrBool !== strOrNumOrBool) {
numOrBool = strOrNumOrBool; // number | boolean
}
else {
var r3: string | number | boolean = strOrNumOrBool; // string | number | boolean
}
@@ -0,0 +1,46 @@
var str: string;
var bool: boolean;
var num: number;
var strOrNum: string | number;
var strOrNumOrBool: string | number | boolean;
var numOrBool: number | boolean;
class C { private p; }
var c: C;
var cOrBool: C| boolean;
var strOrNumOrBoolOrC: string | number | boolean | C;
// A type guard of the form expr1 || expr2
// - when true, narrows the type of x to T1 | T2, where T1 is the type of x narrowed by expr1 when true,
// and T2 is the type of x narrowed by expr1 when false and then by expr2 when true, or
// - when false, narrows the type of x by expr1 when false and then by expr2 when false.
// (typeguard1 || typeguard2)
if (typeof strOrNumOrBool === "string" || typeof strOrNumOrBool === "number") {
strOrNum = strOrNumOrBool; // string | number
}
else {
bool = strOrNumOrBool; // boolean
}
// (typeguard1 || typeguard2 || typeguard3)
if (typeof strOrNumOrBoolOrC === "string" || typeof strOrNumOrBoolOrC === "number" || typeof strOrNumOrBoolOrC === "boolean") {
strOrNumOrBool = strOrNumOrBoolOrC; // string | number | boolean
}
else {
c = strOrNumOrBoolOrC; // C
}
// (typeguard1 || typeguard2 || typeguard11(onAnotherType))
if (typeof strOrNumOrBoolOrC === "string" || typeof strOrNumOrBoolOrC === "number" || typeof strOrNumOrBool !== "boolean") {
var r1: string | number | boolean | C = strOrNumOrBoolOrC; // string | number | boolean | C
var r2: string | number | boolean = strOrNumOrBool;
}
else {
cOrBool = strOrNumOrBoolOrC; // C | boolean
bool = strOrNumOrBool; // boolean
}
// (typeguard1) || simpleExpr
if (typeof strOrNumOrBool === "string" || numOrBool !== strOrNumOrBool) {
var r3: string | number | boolean = strOrNumOrBool; // string | number | boolean
}
else {
numOrBool = strOrNumOrBool; // number | boolean
}
@@ -0,0 +1,30 @@
// A type guard of the form x instanceof C, where C is of a subtype of the global type 'Function'
// and C has a property named 'prototype'
// - when true, narrows the type of x to the type of the 'prototype' property in C provided
// it is a subtype of the type of x, or
// - when false, has no effect on the type of x.
class C1 {
p1: string;
}
class C2 {
p2: number;
}
class D1 extends C1 {
p3: number;
}
var str: string;
var num: number;
var strOrNum: string | number;
var c1Orc2: C1 | C2;
str = c1Orc2 instanceof C1 && c1Orc2.p1; // C1
num = c1Orc2 instanceof C2 && c1Orc2.p2; // C2
str = c1Orc2 instanceof D1 && c1Orc2.p1; // D1
num = c1Orc2 instanceof D1 && c1Orc2.p3; // D1
var c2Ord1: C2 | D1;
num = c2Ord1 instanceof C2 && c2Ord1.p2; // C2
num = c2Ord1 instanceof D1 && c2Ord1.p3; // D1
str = c2Ord1 instanceof D1 && c2Ord1.p1; // D1
var r2: D1 | C2 = c2Ord1 instanceof C1 && c2Ord1; // C2 | D1
@@ -0,0 +1,38 @@
// A type guard of the form x instanceof C, where C is of a subtype of the global type 'Function'
// and C has a property named 'prototype'
// - when true, narrows the type of x to the type of the 'prototype' property in C provided
// it is a subtype of the type of x, or
// - when false, has no effect on the type of x.
interface C1 {
(): C1;
prototype: C1;
p1: string;
}
interface C2 {
(): C2;
prototype: C2;
p2: number;
}
interface D1 extends C1 {
prototype: D1;
p3: number;
}
var str: string;
var num: number;
var strOrNum: string | number;
var c1: C1;
var c2: C2;
var d1: D1;
var c1Orc2: C1 | C2;
str = c1Orc2 instanceof c1 && c1Orc2.p1; // C1
num = c1Orc2 instanceof c2 && c1Orc2.p2; // C2
str = c1Orc2 instanceof d1 && c1Orc2.p1; // C1
num = c1Orc2 instanceof d1 && c1Orc2.p3; // D1
var c2Ord1: C2 | D1;
num = c2Ord1 instanceof c2 && c2Ord1.p2; // C2
num = c2Ord1 instanceof d1 && c2Ord1.p3; // D1
str = c2Ord1 instanceof d1 && c2Ord1.p1; // D1
var r2: D1 | C2 = c2Ord1 instanceof c1 && c2Ord1; // C2 | D1
@@ -0,0 +1,53 @@
var str: string;
var bool: boolean;
var num: number;
var strOrNum: string | number;
var strOrNumOrBool: string | number | boolean;
var numOrBool: number | boolean;
// A type guard of the form !expr
// - when true, narrows the type of x by expr when false, or
// - when false, narrows the type of x by expr when true.
// !typeguard1
if (!(typeof strOrNum === "string")) {
num === strOrNum; // number
}
else {
str = strOrNum; // string
}
// !(typeguard1 || typeguard2)
if (!(typeof strOrNumOrBool === "string" || typeof strOrNumOrBool === "number")) {
bool = strOrNumOrBool; // boolean
}
else {
strOrNum = strOrNumOrBool; // string | number
}
// !(typeguard1) || !(typeguard2)
if (!(typeof strOrNumOrBool !== "string") || !(typeof strOrNumOrBool !== "number")) {
strOrNum = strOrNumOrBool; // string | number
}
else {
bool = strOrNumOrBool; // boolean
}
// !(typeguard1 && typeguard2)
if (!(typeof strOrNumOrBool !== "string" && typeof strOrNumOrBool !== "number")) {
strOrNum = strOrNumOrBool; // string | number
}
else {
bool = strOrNumOrBool; // boolean
}
// !(typeguard1) && !(typeguard2)
if (!(typeof strOrNumOrBool === "string") && !(typeof strOrNumOrBool === "number")) {
bool = strOrNumOrBool; // boolean
}
else {
strOrNum = strOrNumOrBool; // string | number
}
// !(typeguard1) && simpleExpr
if (!(typeof strOrNumOrBool === "string") && numOrBool !== strOrNumOrBool) {
numOrBool = strOrNumOrBool; // number | boolean
}
else {
var r1: string | number | boolean = strOrNumOrBool; // string | number | boolean
}
@@ -0,0 +1,87 @@
class C { private p: string };
var str: string;
var bool: boolean;
var num: number;
var strOrNum: string | number;
var strOrBool: string | boolean;
var numOrBool: number | boolean
var strOrNumOrBool: string | number | boolean;
var strOrC: string | C;
var numOrC: number | C;
var boolOrC: boolean | C;
var c: C;
// A type guard of the form typeof x === s,
// where s is a string literal with the value 'string', 'number', or 'boolean',
// - when true, narrows the type of x to the given primitive type, or
// - when false, removes the primitive type from the type of x.
if (typeof strOrBool === "boolean") {
bool = strOrBool; // boolean
}
else {
str = strOrBool; // string
}
if (typeof numOrBool === "boolean") {
bool = numOrBool; // boolean
}
else {
num = numOrBool; // number
}
if (typeof strOrNumOrBool === "boolean") {
bool = strOrNumOrBool; // boolean
}
else {
strOrNum = strOrNumOrBool; // string | number
}
if (typeof boolOrC === "boolean") {
bool = boolOrC; // boolean
}
else {
c = boolOrC; // C
}
// Narrowing occurs only if target type is a subtype of variable type
if (typeof strOrNum === "boolean") {
var z1: string | number = strOrNum; // string | number
}
else {
var z2: string | number = strOrNum; // string | number
}
// A type guard of the form typeof x !== s, where s is a string literal,
// - when true, narrows the type of x by typeof x === s when false, or
// - when false, narrows the type of x by typeof x === s when true.
if (typeof strOrBool !== "boolean") {
str = strOrBool; // string
}
else {
bool = strOrBool; // boolean
}
if (typeof numOrBool !== "boolean") {
num = numOrBool; // number
}
else {
bool = numOrBool; // boolean
}
if (typeof strOrNumOrBool !== "boolean") {
strOrNum = strOrNumOrBool; // string | number
}
else {
bool = strOrNumOrBool; // boolean
}
if (typeof boolOrC !== "boolean") {
c = boolOrC; // C
}
else {
bool = boolOrC; // boolean
}
// Narrowing occurs only if target type is a subtype of variable type
if (typeof strOrNum !== "boolean") {
var z1: string | number = strOrNum; // string | number
}
else {
var z2: string | number = strOrNum; // string | number
}
@@ -0,0 +1,35 @@
class C { private p: string };
var strOrNum: string | number;
var strOrBool: string | boolean;
var numOrBool: number | boolean
var strOrC: string | C;
// typeof x == s has not effect on typeguard
if (typeof strOrNum == "string") {
var r1 = strOrNum; // string | number
}
else {
var r1 = strOrNum; // string | number
}
if (typeof strOrBool == "boolean") {
var r2 = strOrBool; // string | boolean
}
else {
var r2 = strOrBool; // string | boolean
}
if (typeof numOrBool == "number") {
var r3 = numOrBool; // number | boolean
}
else {
var r3 = numOrBool; // number | boolean
}
if (typeof strOrC == "Object") {
var r4 = strOrC; // string | C
}
else {
var r4 = strOrC; // string | C
}
@@ -0,0 +1,35 @@
class C { private p: string };
var strOrNum: string | number;
var strOrBool: string | boolean;
var numOrBool: number | boolean
var strOrC: string | C;
// typeof x != s has not effect on typeguard
if (typeof strOrNum != "string") {
var r1 = strOrNum; // string | number
}
else {
var r1 = strOrNum; // string | number
}
if (typeof strOrBool != "boolean") {
var r2 = strOrBool; // string | boolean
}
else {
var r2 = strOrBool; // string | boolean
}
if (typeof numOrBool != "number") {
var r3 = numOrBool; // number | boolean
}
else {
var r3 = numOrBool; // number | boolean
}
if (typeof strOrC != "Object") {
var r4 = strOrC; // string | C
}
else {
var r4 = strOrC; // string | C
}
@@ -0,0 +1,86 @@
class C { private p: string };
var str: string;
var bool: boolean;
var num: number;
var strOrNum: string | number;
var strOrBool: string | boolean;
var numOrBool: number | boolean
var strOrNumOrBool: string | number | boolean;
var strOrC: string | C;
var numOrC: number | C;
var boolOrC: boolean | C;
var c: C;
// A type guard of the form typeof x === s,
// where s is a string literal with the value 'string', 'number', or 'boolean',
// - when true, narrows the type of x to the given primitive type, or
// - when false, removes the primitive type from the type of x.
if (typeof strOrNum === "number") {
num = strOrNum; // number
}
else {
str === strOrNum; // string
}
if (typeof numOrBool === "number") {
num = numOrBool; // number
}
else {
var x: number | boolean = numOrBool; // number | boolean
}
if (typeof strOrNumOrBool === "number") {
num = strOrNumOrBool; // number
}
else {
strOrBool = strOrNumOrBool; // string | boolean
}
if (typeof numOrC === "number") {
num = numOrC; // number
}
else {
c = numOrC; // C
}
// Narrowing occurs only if target type is a subtype of variable type
if (typeof strOrBool === "number") {
var y1: string | boolean = strOrBool; // string | boolean
}
else {
var y2: string | boolean = strOrBool; // string | boolean
}
// A type guard of the form typeof x !== s, where s is a string literal,
// - when true, narrows the type of x by typeof x === s when false, or
// - when false, narrows the type of x by typeof x === s when true.
if (typeof strOrNum !== "number") {
str === strOrNum; // string
}
else {
num = strOrNum; // number
}
if (typeof numOrBool !== "number") {
var x: number | boolean = numOrBool; // number | boolean
}
else {
num = numOrBool; // number
}
if (typeof strOrNumOrBool !== "number") {
strOrBool = strOrNumOrBool; // string | boolean
}
else {
num = strOrNumOrBool; // number
}
if (typeof numOrC !== "number") {
c = numOrC; // C
}
else {
num = numOrC; // number
}
// Narrowing occurs only if target type is a subtype of variable type
if (typeof strOrBool !== "number") {
var y1: string | boolean = strOrBool; // string | boolean
}
else {
var y2: string | boolean = strOrBool; // string | boolean
}
@@ -0,0 +1,76 @@
class C { private p: string };
var str: string;
var bool: boolean;
var num: number;
var strOrNum: string | number;
var strOrBool: string | boolean;
var numOrBool: number | boolean
var strOrNumOrBool: string | number | boolean;
var strOrC: string | C;
var numOrC: number | C;
var boolOrC: boolean | C;
var emptyObj: {};
var c: C;
// A type guard of the form typeof x === s,
// where s is a string literal with any value but 'string', 'number' or 'boolean',
// - when true, removes the primitive types string, number, and boolean from the type of x, or
// - when false, has no effect on the type of x.
if (typeof strOrC === "Object") {
c = strOrC; // C
}
else {
var r2: string | C = strOrC; // string | C
}
if (typeof numOrC === "Object") {
c = numOrC; // C
}
else {
var r3: number | C = numOrC; // number | C
}
if (typeof boolOrC === "Object") {
c = boolOrC; // C
}
else {
var r4: boolean | C = boolOrC; // boolean | C
}
// Narrowing occurs only if target type is a subtype of variable type
if (typeof strOrNumOrBool === "Object") {
var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean
}
else {
var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean
}
// A type guard of the form typeof x !== s, where s is a string literal,
// - when true, narrows the type of x by typeof x === s when false, or
// - when false, narrows the type of x by typeof x === s when true.
if (typeof strOrC !== "Object") {
var r2: string | C = strOrC; // string | C
}
else {
c = strOrC; // C
}
if (typeof numOrC !== "Object") {
var r3: number | C = numOrC; // number | C
}
else {
c = numOrC; // C
}
if (typeof boolOrC !== "Object") {
var r4: boolean | C = boolOrC; // boolean | C
}
else {
c = boolOrC; // C
}
// Narrowing occurs only if target type is a subtype of variable type
if (typeof strOrNumOrBool !== "Object") {
var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean
}
else {
var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean
}
@@ -0,0 +1,86 @@
class C { private p: string };
var str: string;
var bool: boolean;
var num: number;
var strOrNum: string | number;
var strOrBool: string | boolean;
var numOrBool: number | boolean
var strOrNumOrBool: string | number | boolean;
var strOrC: string | C;
var numOrC: number | C;
var boolOrC: boolean | C;
var c: C;
// A type guard of the form typeof x === s,
// where s is a string literal with the value 'string', 'number', or 'boolean',
// - when true, narrows the type of x to the given primitive type, or
// - when false, removes the primitive type from the type of x.
if (typeof strOrNum === "string") {
str = strOrNum; // string
}
else {
num === strOrNum; // number
}
if (typeof strOrBool === "string") {
str = strOrBool; // string
}
else {
bool = strOrBool; // boolean
}
if (typeof strOrNumOrBool === "string") {
str = strOrNumOrBool; // string
}
else {
numOrBool = strOrNumOrBool; // number | boolean
}
if (typeof strOrC === "string") {
str = strOrC; // string
}
else {
c = strOrC; // C
}
// Narrowing occurs only if target type is a subtype of variable type
if (typeof numOrBool === "string") {
var x1: number | boolean = numOrBool; // number | boolean
}
else {
var x2: number | boolean = numOrBool; // number | boolean
}
// A type guard of the form typeof x !== s, where s is a string literal,
// - when true, narrows the type of x by typeof x === s when false, or
// - when false, narrows the type of x by typeof x === s when true.
if (typeof strOrNum !== "string") {
num === strOrNum; // number
}
else {
str = strOrNum; // string
}
if (typeof strOrBool !== "string") {
bool = strOrBool; // boolean
}
else {
str = strOrBool; // string
}
if (typeof strOrNumOrBool !== "string") {
numOrBool = strOrNumOrBool; // number | boolean
}
else {
str = strOrNumOrBool; // string
}
if (typeof strOrC !== "string") {
c = strOrC; // C
}
else {
str = strOrC; // string
}
// Narrowing occurs only if target type is a subtype of variable type
if (typeof numOrBool !== "string") {
var x1: number | boolean = numOrBool; // number | boolean
}
else {
var x2: number | boolean = numOrBool; // number | boolean
}
@@ -0,0 +1,36 @@
// Also note that it is possible to defeat a type guard by calling a function that changes the
// type of the guarded variable.
function foo(x: number | string) {
function f() {
x = 10;
}
if (typeof x === "string") {
f();
return x.length; // string
}
else {
return x++; // number
}
}
function foo2(x: number | string) {
if (typeof x === "string") {
return x.length; // string
}
else {
var f = function () {
return x * x;
};
}
x = "hello";
f();
}
function foo3(x: number | string) {
if (typeof x === "string") {
return x.length; // string
}
else {
var f = () => x * x;
}
x = "hello";
f();
}
@@ -0,0 +1,103 @@
//@target: es5
// Note that type guards affect types of variables and parameters only and
// have no effect on members of objects such as properties.
// variables in global
var num: number;
var strOrNum: string | number;
var var1: string | number;
class ClassWithAccessors {
// Inside public accessor getter
get p1() {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
return strOrNum;
}
// Inside public accessor setter
set p1(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// parameter of function declaration
num = typeof param === "string" && param.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
}
// Inside private accessor getter
private get pp1() {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
return strOrNum;
}
// Inside private accessor setter
private set pp1(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// parameter of function declaration
num = typeof param === "string" && param.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
}
// Inside static accessor getter
static get s1() {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
return strOrNum;
}
// Inside static accessor setter
static set s1(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// parameter of function declaration
num = typeof param === "string" && param.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
}
// Inside private static accessor getter
private static get ss1() {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
return strOrNum;
}
// Inside private static accessor setter
private static set ss1(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// parameter of function declaration
num = typeof param === "string" && param.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
}
}
@@ -0,0 +1,67 @@
// Note that type guards affect types of variables and parameters only and
// have no effect on members of objects such as properties.
// variables in global
var num: number;
var var1: string | number;
class C1 {
constructor(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
// parameters in function declaration
num = typeof param === "string" && param.length; // string
}
// Inside function declaration
private p1(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
// parameters in function declaration
num = typeof param === "string" && param.length; // string
}
// Inside function declaration
p2(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
// parameters in function declaration
num = typeof param === "string" && param.length; // string
}
// Inside function declaration
private static s1(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
// parameters in function declaration
num = typeof param === "string" && param.length; // string
}
// Inside function declaration
static s2(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
// parameters in function declaration
num = typeof param === "string" && param.length; // string
}
}
@@ -0,0 +1,97 @@
// 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
: ((b = x) // x is number | boolean | string - changed in true branch
&& typeof x === "number"
&& x); // x is number
}
@@ -0,0 +1,24 @@
//@module: commonjs
// Note that type guards affect types of variables and parameters only and
// have no effect on members of objects such as properties.
// local variable in external module
var num: number;
var var1: string | number;
if (typeof var1 === "string") {
num = var1.length; // string
}
else {
num = var1; // number
}
// exported variable in external module
var strOrNum: string | number;
export var var2: string | number;
if (typeof var2 === "string") {
// export makes the var property and not variable
strOrNum = var2; // string | number
}
else {
strOrNum = var2; // number | string
}
@@ -0,0 +1,87 @@
// Note that type guards affect types of variables and parameters only and
// have no effect on members of objects such as properties.
// variables in global
var num: number;
var var1: string | number;
// Inside function declaration
function f(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
// parameters in function declaration
num = typeof param === "string" && param.length; // string
}
// local function declaration
function f1(param: string | number) {
var var2: string | number;
function f2(param1: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables from outer function declaration
num = typeof var2 === "string" && var2.length; // string
// parameters in outer declaration
num = typeof param === "string" && param.length; // string
// local
var var3: string | number;
num = typeof var3 === "string" && var3.length; // string
num = typeof param1 === "string" && param1.length; // string
}
}
// Function expression
function f2(param: string | number) {
// variables in function declaration
var var2: string | number;
// variables in function expressions
var r = function (param1: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables from outer function declaration
num = typeof var2 === "string" && var2.length; // string
// parameters in outer declaration
num = typeof param === "string" && param.length; // string
// local
var var3: string | number;
num = typeof var3 === "string" && var3.length; // string
num = typeof param1 === "string" && param1.length; // string
} (param);
}
// Arrow expression
function f3(param: string | number) {
// variables in function declaration
var var2: string | number;
// variables in function expressions
var r = ((param1: string | number) => {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables from outer function declaration
num = typeof var2 === "string" && var2.length; // string
// parameters in outer declaration
num = typeof param === "string" && param.length; // string
// local
var var3: string | number;
num = typeof var3 === "string" && var3.length; // string
num = typeof param1 === "string" && param1.length; // string
})(param);
}
// Return type of function
// Inside function declaration
var strOrNum: string | number;
function f4() {
var var2: string | number = strOrNum;
return var2;
}
strOrNum = typeof f4() === "string" && f4(); // string | number
@@ -0,0 +1,79 @@
// typeguards are scoped in function/module block
function foo(x: number | string | boolean) {
return typeof x === "string"
? x
: function f() {
var b = x; // number | boolean
return typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
} ();
}
function foo2(x: number | string | boolean) {
return typeof x === "string"
? x
: function f(a: number | boolean) {
var b = x; // new scope - number | boolean
return typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
} (x); // x here is narrowed to number | boolean
}
function foo3(x: number | string | boolean) {
return typeof x === "string"
? x
: (() => {
var b = x; // new scope - number | boolean
return typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
})();
}
function foo4(x: number | string | boolean) {
return typeof x === "string"
? x
: ((a: number | boolean) => {
var b = x; // new scope - number | boolean
return typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
})(x); // x here is narrowed to number | boolean
}
// Type guards affect nested function expressions, but not nested function declarations
function foo5(x: number | string | boolean) {
if (typeof x === "string") {
var y = x; // string;
function foo() {
var z = x; // number | string | boolean, type guard has no effect
}
}
}
module m {
var x: number | string | boolean;
module m2 {
var b = x; // new scope - number | boolean | string
var y: string;
if (typeof x === "string") {
y = x // string;
} else {
y = typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
}
}
}
module m1 {
var x: number | string | boolean;
module m2.m3 {
var b = x; // new scope - number | boolean | string
var y: string;
if (typeof x === "string") {
y = x // string;
} else {
y = typeof x === "boolean"
? x.toString() // boolean
: x.toString(); // number
}
}
}
@@ -0,0 +1,12 @@
// Note that type guards affect types of variables and parameters only and
// have no effect on members of objects such as properties.
// variables in global
var num: number;
var var1: string | number;
if (typeof var1 === "string") {
num = var1.length; // string
}
else {
num = var1; // number
}
@@ -0,0 +1,148 @@
// In the true branch statement of an ‘if’ statement,
// the type of a variable or parameter is narrowed by any type guard in the ‘if’ condition when true,
// provided the true branch statement contains no assignments to the variable or parameter.
// In the false branch statement of an ‘if’ statement,
// the type of a variable or parameter is narrowed by any type guard in the ‘if’ condition when false,
// provided the false branch statement contains no assignments to the variable or parameter
function foo(x: number | string) {
if (typeof x === "string") {
return x.length; // string
}
else {
return x++; // number
}
}
function foo2(x: number | string) {
// x is assigned in the if true branch, the type is not narrowed
if (typeof x === "string") {
x = 10;
return x; // string | number
}
else {
return x; // string | number
}
}
function foo3(x: number | string) {
// x is assigned in the if true branch, the type is not narrowed
if (typeof x === "string") {
x = "Hello"; // even though assigned using same type as narrowed expression
return x; // string | number
}
else {
return x; // string | number
}
}
function foo4(x: number | string) {
// false branch updates the variable - so here it is not number
if (typeof x === "string") {
return x; // string | number
}
else {
x = 10; // even though assigned number - this should result in x to be string | number
return x; // string | number
}
}
function foo5(x: number | string) {
// false branch updates the variable - so here it is not number
if (typeof x === "string") {
return x; // string | number
}
else {
x = "hello";
return x; // string | number
}
}
function foo6(x: number | string) {
// Modify in both branches
if (typeof x === "string") {
x = 10;
return x; // string | number
}
else {
x = "hello";
return x; // string | number
}
}
function foo7(x: number | string | boolean) {
if (typeof x === "string") {
return x === "hello"; // string
}
else if (typeof x === "boolean") {
return x; // boolean
}
else {
return x == 10; // number
}
}
function foo8(x: number | string | boolean) {
if (typeof x === "string") {
return x === "hello"; // string
}
else {
var b: number | boolean = x; // number | boolean
if (typeof x === "boolean") {
return x; // boolean
}
else {
return x == 10; // number
}
}
}
function foo9(x: number | string) {
var y = 10;
if (typeof x === "string") {
// usage of x or assignment to separate variable shouldn't cause narrowing of type to stop
y = x.length;
return x === "hello"; // string
}
else {
return x == 10; // number
}
}
function foo10(x: number | string | boolean) {
// Mixing typeguard narrowing in if statement with conditional expression typeguard
if (typeof x === "string") {
return x === "hello"; // string
}
else {
var y: boolean | string;
var b = x; // number | boolean
return typeof x === "number"
? x === 10 // number
: x; // x should be boolean
}
}
function foo11(x: number | string | boolean) {
// Mixing typeguard narrowing in if statement with conditional expression typeguard
// Assigning value to x deep inside another guard stops narrowing of type too
if (typeof x === "string") {
return x; // string | number | boolean - x changed in else branch
}
else {
var y: number| boolean | string;
var b = x; // number | boolean | string - because below we are changing value of x in if statement
return typeof x === "number"
? (
// change value of x
x = 10 && x.toString() // number | boolean | string
)
: (
// do not change value
y = x && x.toString() // number | boolean | string
);
}
}
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
}
else {
x = 10;
var b = x; // number | boolean | string
return typeof x === "number"
? x.toString() // number
: x.toString(); // boolean | string
}
}
@@ -0,0 +1,86 @@
// Note that type guards affect types of variables and parameters only and
// have no effect on members of objects such as properties.
// variables in global
var num: number;
var strOrNum: string | number;
var var1: string | number;
// Inside module
module m1 {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in module declaration
var var2: string | number;
if (typeof var2 === "string") {
num = var2.length; // string
}
else {
num = var2; // number
}
// exported variable in the module
export var var3: string | number;
if (typeof var3 === "string") {
strOrNum = var3; // string | number
}
else {
strOrNum = var3; // string | number
}
}
// local module
module m2 {
var var2: string | number;
export var var3: string | number;
module m3 {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// local variables from outer module declaration
num = typeof var2 === "string" && var2.length; // string
// exported variable from outer the module
strOrNum = typeof var3 === "string" && var3; // string | number
// variables in module declaration
var var4: string | number;
if (typeof var4 === "string") {
num = var4.length; // string
}
else {
num = var4; // number
}
// exported variable in the module
export var var5: string | number;
if (typeof var5 === "string") {
strOrNum = var5; // string | number
}
else {
strOrNum = var5; // string | number
}
}
}
// Dotted module
module m3.m4 {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in module declaration
var var2: string | number;
if (typeof var2 === "string") {
num = var2.length; // string
}
else {
num = var2; // number
}
// exported variable in the module
export var var3: string | number;
if (typeof var3 === "string") {
strOrNum = var3; // string | number
}
else {
strOrNum = var3; // string | number
}
}
@@ -0,0 +1,27 @@
//@target: es5
// Note that type guards affect types of variables and parameters only and
// have no effect on members of objects such as properties.
var num: number;
var strOrNum: string | number;
class C1 {
private pp1: string | number;
pp2: string | number;
// Inside public accessor getter
get pp3() {
return strOrNum;
}
method() {
strOrNum = typeof this.pp1 === "string" && this.pp1; // string | number
strOrNum = typeof this.pp2 === "string" && this.pp2; // string | number
strOrNum = typeof this.pp3 === "string" && this.pp3; // string | number
}
}
var c1: C1;
strOrNum = typeof c1.pp2 === "string" && c1.pp2; // string | number
strOrNum = typeof c1.pp3 === "string" && c1.pp3; // string | number
var obj1: {
x: string | number;
};
strOrNum = typeof obj1.x === "string" && obj1.x; // string | number
@@ -0,0 +1,55 @@
// 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
// do not change value
: (y = x && x.toString()))); // number | boolean | string
}
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
}
@@ -0,0 +1,55 @@
// 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
// do not change value
: (y = x && x.toString()))); // number | boolean | string
}
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
}
@@ -0,0 +1,51 @@
//@target: es5
// Note that type guards affect types of variables and parameters only and
// have no effect on members of objects such as properties.
// variables in global
var num: number;
var strOrNum: string | number;
var var1: string | number;
var obj1 = {
// Inside method
method(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
// parameters in function declaration
num = typeof param === "string" && param.length; // string
return strOrNum;
},
get prop() {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
return strOrNum;
},
set prop(param: string | number) {
// global vars in function declaration
num = typeof var1 === "string" && var1.length; // string
// variables in function declaration
var var2: string | number;
num = typeof var2 === "string" && var2.length; // string
// parameters in function declaration
num = typeof param === "string" && param.length; // string
}
};
// return expression of the method
strOrNum = typeof obj1.method(strOrNum) === "string" && obj1.method(strOrNum);
// accessing getter property
strOrNum = typeof obj1.prop === "string" && obj1.prop;
@@ -0,0 +1,6 @@
///<reference path="fourslash.ts" />
//// var person: {name:string; id:number} = {n/**/
goTo.marker();
verify.completionListContains("name", /*text*/ undefined, /*documentation*/ undefined, "property");
@@ -0,0 +1,7 @@
/// <reference path="fourslash.ts" />
//// var person: {name:string; id: number} = { n/**/
goTo.marker();
verify.memberListContains('name');
verify.memberListContains('id');
@@ -0,0 +1,7 @@
/// <reference path="fourslash.ts" />
//// var person: {name:string; id: number} = { n/**/
goTo.marker();
verify.memberListContains('name');
verify.memberListContains('id');
@@ -8,4 +8,4 @@ test.markers().forEach(marker => {
goTo.position(marker.position);
verify.completionListItemsCountIsGreaterThan(0)
}}
});
@@ -8,4 +8,4 @@ test.markers().forEach(marker => {
goTo.position(marker.position);
verify.completionListIsEmpty()
}
});
@@ -8,5 +8,5 @@ test.ranges().forEach(targetRange => {
test.ranges().forEach(range => {
verify.referencesAtPositionContains(range);
}
}
});
});
@@ -8,5 +8,5 @@ test.ranges().forEach(targetRange => {
test.ranges().forEach(range => {
verify.referencesAtPositionContains(range);
}
}
});
});
@@ -0,0 +1,19 @@
/// <reference path='fourslash.ts'/>
//// var /*1*/name = "Foo";
////
//// var obj = { /*2*/name };
//// var obj1 = { /*3*/name:name };
//// obj./*4*/name;
goTo.marker('1');
verify.referencesCountIs(3);
goTo.marker('2');
verify.referencesCountIs(4);
goTo.marker('3');
verify.referencesCountIs(1);
goTo.marker('4');
verify.referencesCountIs(2);
@@ -0,0 +1,23 @@
/// <reference path='fourslash.ts'/>
//// var /*1*/dx = "Foo";
////
//// module M { export var /*2*/dx; }
//// module M {
//// var z = 100;
//// export var y = { /*3*/dx, z };
//// }
//// M.y./*4*/dx;
goTo.marker('1');
debugger;
verify.referencesCountIs(1);
goTo.marker('2');
verify.referencesCountIs(2);
goTo.marker('3');
verify.referencesCountIs(3);
goTo.marker('4');
verify.referencesCountIs(2);
@@ -0,0 +1,13 @@
/// <reference path='fourslash.ts' />
////try
////{
//// var x = 1/*1*/
////}
////catch (e)
////{
////}
goTo.marker("1");
edit.insert(";")
verify.currentLineContentIs(" var x = 1;");
@@ -11,4 +11,4 @@ goTo.marker();
edit.insert('}');
goTo.marker('comment');
// Comment below multi-line 'if' condition formatting
verify.currentLineContentIs(' // This is a comment');
verify.currentLineContentIs(' // This is a comment');
@@ -0,0 +1,12 @@
/// <reference path='fourslash.ts' />
////switch (1) {
//// case 1:
//// {
//// /*1*/
//// break;
////}
goTo.marker("1");
edit.insert("}");
verify.currentLineContentIs(" }");
@@ -120,13 +120,13 @@ verify.currentLineContentIs("(arg) => 2;");
goTo.marker("3");
verify.currentLineContentIs("arg => 2;");
goTo.marker("4");
verify.currentLineContentIs("(arg = 1) => 3;");
verify.currentLineContentIs("(arg = 1) => 3;");
goTo.marker("5");
verify.currentLineContentIs("(arg?) => 4;");
goTo.marker("6");
verify.currentLineContentIs("(arg: number) => 5;");
goTo.marker("7");
verify.currentLineContentIs("(arg: number = 0) => 6;");
verify.currentLineContentIs("(arg: number = 0) => 6;");
goTo.marker("8");
verify.currentLineContentIs("(arg?: number) => 7;");
goTo.marker("9");
@@ -134,13 +134,13 @@ verify.currentLineContentIs("(...arg: number[]) => 8;");
goTo.marker("10");
verify.currentLineContentIs("(arg1, arg2) => 12;");
goTo.marker("11");
verify.currentLineContentIs("(arg1 = 1, arg2 = 3) => 13;");
verify.currentLineContentIs("(arg1 = 1, arg2 = 3) => 13;");
goTo.marker("12");
verify.currentLineContentIs("(arg1?, arg2?) => 14;");
goTo.marker("13");
verify.currentLineContentIs("(arg1: number, arg2: number) => 15;");
goTo.marker("14");
verify.currentLineContentIs("(arg1: number = 0, arg2: number = 1) => 16;");
verify.currentLineContentIs("(arg1: number = 0, arg2: number = 1) => 16;");
goTo.marker("15");
verify.currentLineContentIs("(arg1?: number, arg2?: number) => 17;");
goTo.marker("16");
@@ -152,13 +152,13 @@ verify.currentLineContentIs("(() => 21);");
goTo.marker("19");
verify.currentLineContentIs("((arg) => 22);");
goTo.marker("20");
verify.currentLineContentIs("((arg = 1) => 23);");
verify.currentLineContentIs("((arg = 1) => 23);");
goTo.marker("21");
verify.currentLineContentIs("((arg?) => 24);");
goTo.marker("22");
verify.currentLineContentIs("((arg: number) => 25);");
goTo.marker("23");
verify.currentLineContentIs("((arg: number = 0) => 26);");
verify.currentLineContentIs("((arg: number = 0) => 26);");
goTo.marker("24");
verify.currentLineContentIs("((arg?: number) => 27);");
goTo.marker("25");
@@ -170,7 +170,7 @@ verify.currentLineContentIs("false ? () => 41 : null;");
goTo.marker("28");
verify.currentLineContentIs("false ? (arg) => 42 : null;");
goTo.marker("29");
verify.currentLineContentIs("false ? (arg = 1) => 43 : null;");
verify.currentLineContentIs("false ? (arg = 1) => 43 : null;");
goTo.marker("30");
verify.currentLineContentIs("false ? (arg?) => 44 : null;");
goTo.marker("31");
@@ -178,7 +178,7 @@ verify.currentLineContentIs("false ? (arg: number) => 45 : null;");
goTo.marker("32");
verify.currentLineContentIs("false ? (arg?: number) => 46 : null;");
goTo.marker("33");
verify.currentLineContentIs("false ? (arg?: number = 0) => 47 : null;");
verify.currentLineContentIs("false ? (arg?: number = 0) => 47 : null;");
goTo.marker("34");
verify.currentLineContentIs("false ? (...arg: number[]) => 48 : null;");
goTo.marker("35");
@@ -186,7 +186,7 @@ verify.currentLineContentIs("false ? (() => 51) : null;");
goTo.marker("36");
verify.currentLineContentIs("false ? ((arg) => 52) : null;");
goTo.marker("37");
verify.currentLineContentIs("false ? ((arg = 1) => 53) : null;");
verify.currentLineContentIs("false ? ((arg = 1) => 53) : null;");
goTo.marker("38");
verify.currentLineContentIs("false ? ((arg?) => 54) : null;");
goTo.marker("39");
@@ -194,7 +194,7 @@ verify.currentLineContentIs("false ? ((arg: number) => 55) : null;");
goTo.marker("40");
verify.currentLineContentIs("false ? ((arg?: number) => 56) : null;");
goTo.marker("41");
verify.currentLineContentIs("false ? ((arg?: number = 0) => 57) : null;");
verify.currentLineContentIs("false ? ((arg?: number = 0) => 57) : null;");
goTo.marker("42");
verify.currentLineContentIs("false ? ((...arg: number[]) => 58) : null;");
goTo.marker("43");
@@ -202,7 +202,7 @@ verify.currentLineContentIs("false ? null : () => 61;");
goTo.marker("44");
verify.currentLineContentIs("false ? null : (arg) => 62;");
goTo.marker("45");
verify.currentLineContentIs("false ? null : (arg = 1) => 63;");
verify.currentLineContentIs("false ? null : (arg = 1) => 63;");
goTo.marker("46");
verify.currentLineContentIs("false ? null : (arg?) => 64;");
goTo.marker("47");
@@ -210,7 +210,7 @@ verify.currentLineContentIs("false ? null : (arg: number) => 65;");
goTo.marker("48");
verify.currentLineContentIs("false ? null : (arg?: number) => 66;");
goTo.marker("49");
verify.currentLineContentIs("false ? null : (arg?: number = 0) => 67;");
verify.currentLineContentIs("false ? null : (arg?: number = 0) => 67;");
goTo.marker("50");
verify.currentLineContentIs("false ? null : (...arg: number[]) => 68;");
goTo.marker("51");
@@ -220,13 +220,13 @@ verify.currentLineContentIs("((a?) => { return a; }) ? (b) => (c) => 81 : (c) =>
goTo.marker("53");
verify.currentLineContentIs("((arg) => 90) instanceof Function;");
goTo.marker("54");
verify.currentLineContentIs("((arg = 1) => 91) instanceof Function;");
verify.currentLineContentIs("((arg = 1) => 91) instanceof Function;");
goTo.marker("55");
verify.currentLineContentIs("((arg?) => 92) instanceof Function;");
goTo.marker("56");
verify.currentLineContentIs("((arg: number) => 93) instanceof Function;");
goTo.marker("57");
verify.currentLineContentIs("((arg: number = 1) => 94) instanceof Function;");
verify.currentLineContentIs("((arg: number = 1) => 94) instanceof Function;");
goTo.marker("58");
verify.currentLineContentIs("((arg?: number) => 95) instanceof Function;");
goTo.marker("59");
@@ -237,13 +237,13 @@ verify.currentLineContentIs("'' + ((arg) => 100);");
goTo.marker("61");
verify.currentLineContentIs("((arg) => 0) + '' + ((arg) => 101);");
goTo.marker("62");
verify.currentLineContentIs("((arg = 1) => 0) + '' + ((arg = 2) => 102);");
verify.currentLineContentIs("((arg = 1) => 0) + '' + ((arg = 2) => 102);");
goTo.marker("63");
verify.currentLineContentIs("((arg?) => 0) + '' + ((arg?) => 103);");
goTo.marker("64");
verify.currentLineContentIs("((arg: number) => 0) + '' + ((arg: number) => 104);");
goTo.marker("65");
verify.currentLineContentIs("((arg: number = 1) => 0) + '' + ((arg: number = 2) => 105);");
verify.currentLineContentIs("((arg: number = 1) => 0) + '' + ((arg: number = 2) => 105);");
goTo.marker("66");
verify.currentLineContentIs("((arg?: number) => 0) + '' + ((arg?: number) => 106);");
goTo.marker("67");
@@ -273,17 +273,17 @@ verify.currentLineContentIs(" (a, b?) => 114,");
goTo.marker("79");
verify.currentLineContentIs(" (a: number) => 115,");
goTo.marker("80");
verify.currentLineContentIs(" (a: number = 0) => 116,");
verify.currentLineContentIs(" (a: number = 0) => 116,");
goTo.marker("81");
verify.currentLineContentIs(" (a = 0) => 117,");
verify.currentLineContentIs(" (a = 0) => 117,");
goTo.marker("82");
verify.currentLineContentIs(" (a: number = 0) => 118,");
verify.currentLineContentIs(" (a: number = 0) => 118,");
goTo.marker("83");
verify.currentLineContentIs(" (a?, b?: number) => 118,");
goTo.marker("84");
verify.currentLineContentIs(" (...a: number[]) => 119,");
goTo.marker("85");
verify.currentLineContentIs(" (a, b = 0, ...c: number[]) => 120,");
verify.currentLineContentIs(" (a, b = 0, ...c: number[]) => 120,");
goTo.marker("86");
verify.currentLineContentIs(" (a) => (b) => (c) => 121,");
goTo.marker("87");
@@ -0,0 +1,12 @@
/// <reference path='fourslash.ts' />
////if (true) {
////}
////else {
//// if (true) {
//// /*1*/
////}
goTo.marker("1");
edit.insert("}")
verify.currentLineContentIs(" }");
@@ -0,0 +1,14 @@
/// <reference path='fourslash.ts' />
////var x = function() {
//// if (true) {
//// /*1*/} else {/*2*/
////}
////
////// newline at the end of the file
goTo.marker("2");
edit.insertLine("");
goTo.marker("1");
// else formating should not be affected
verify.currentLineContentIs(' } else {');
@@ -0,0 +1,27 @@
/// <reference path='fourslash.ts'/>
/////*1*/ module My.App {
/////*2*/export var appModule = angular.module("app", [
/////*3*/ ]).config([() => {
/////*4*/ configureStates
/////*5*/($stateProvider);
/////*6*/}]).run(My.App.setup);
/////*7*/ }
format.document()
goTo.marker("1");
verify.currentLineContentIs("module My.App {");
goTo.marker("2");
verify.currentLineContentIs(" export var appModule = angular.module(\"app\", [");
goTo.marker("3");
verify.currentLineContentIs(" ]).config([() => {");
goTo.marker("4");
verify.currentLineContentIs(" configureStates");
goTo.marker("5");
verify.currentLineContentIs(" ($stateProvider);");
goTo.marker("6");
verify.currentLineContentIs(" }]).run(My.App.setup);");
goTo.marker("7");
verify.currentLineContentIs("}");
@@ -135,9 +135,9 @@ verify.currentLineContentIs(" return 0");
goTo.marker("51");
verify.currentLineContentIs("}).then(function(doc) {");
goTo.marker("52");
verify.currentLineContentIs(" return 1");
verify.currentLineContentIs(" return 1");
goTo.marker("53");
verify.currentLineContentIs(" });");
verify.currentLineContentIs("});");
goTo.marker("54");
verify.currentLineContentIs("if (1)");
goTo.marker("55");
@@ -4,7 +4,7 @@
//// export enum NodeType {/*2*/
//// Error,/*3*/
//// Comment,/*4*/
//// } /*5*/
//// } /*5*/
//// export enum foob/*6*/
//// {
//// Blah=1, Bleah=2/*7*/
@@ -25,7 +25,7 @@ verify.currentLineContentIs(" }");
goTo.marker("6");
verify.currentLineContentIs(" export enum foob {");
goTo.marker("7");
verify.currentLineContentIs(" Blah= 1, Bleah= 2");
verify.currentLineContentIs(" Blah = 1, Bleah = 2");
goTo.marker("8");
verify.currentLineContentIs(" }");
goTo.marker("9");
@@ -15,8 +15,8 @@ verify.currentLineContentIs('foo(): Bar { }');
goTo.marker('2');
verify.currentLineContentIs('function Foo() # { }');
goTo.marker('3');
verify.currentLineContentIs('4+:5');
verify.currentLineContentIs('4 +:5');
goTo.marker('4');
verify.currentLineContentIs(' : T) { }');
goTo.marker('5');
verify.currentLineContentIs('var x =');
verify.currentLineContentIs('var x =');
@@ -0,0 +1,12 @@
///<reference path="fourslash.ts"/>
////String.call `${123}`/*1*/
////String.call `${123} ${456}`/*2*/
goTo.marker("1");
edit.insert(";");
verify.currentLineContentIs("String.call `${123}`;");
goTo.marker("2");
edit.insert(";");
verify.currentLineContentIs("String.call `${123} ${456}`;");
@@ -1,8 +0,0 @@
///<reference path="fourslash.ts" />
////class C {
//// /**/p;
////}
goTo.marker();
verify.implementorsCountIs(0);
@@ -1,6 +0,0 @@
///<reference path="fourslash.ts" />
////function fo/**/o() {
////}
goTo.marker();
verify.implementorsCountIs(0);
@@ -51,4 +51,4 @@ for (var i = 1; i <= test.markers().length; i++) {
verify.occurrencesAtPositionCount(1); // 'return' is an instance member
break;
}
});
}
@@ -0,0 +1,25 @@
/// <reference path='fourslash.ts' />
//// var /*valueDeclaration1*/name = "hello";
//// var /*valueDeclaration2*/id = 100000;
//// declare var /*valueDeclaration3*/id;
//// var obj = {/*valueDefinition1*/name, /*valueDefinition2*/id};
//// obj./*valueReference1*/name;
//// obj./*valueReference2*/id;
goTo.marker("valueDefinition1");
goTo.definition();
verify.caretAtMarker("valueDeclaration1");
goTo.marker("valueDefinition2");
goTo.definition(0);
verify.caretAtMarker("valueDeclaration2");
goTo.definition(1);
verify.caretAtMarker("valueDeclaration3");
goTo.marker("valueReference1");
goTo.definition();
verify.caretAtMarker("valueDefinition1");
goTo.marker("valueReference2");
goTo.definition();
verify.caretAtMarker("valueDefinition2");
@@ -11,8 +11,8 @@
debugger;
format.document();
goTo.marker('1');
verify.currentLineContentIs('function test() /* %^ */');
verify.currentLineContentIs('function test() /* %^ */ {');
goTo.marker('2');
verify.currentLineContentIs(' if (true) /* %^ */');
verify.currentLineContentIs(' if (true) /* %^ */ {');
goTo.marker('3');
verify.currentLineContentIs('}');
@@ -0,0 +1,21 @@
/// <reference path='fourslash.ts' />
//// var name1 = undefined, id1 = undefined;
//// var /*obj1*/obj1 = {/*name1*/name1, /*id1*/id1};
//// var name2 = "Hello";
//// var id2 = 10000;
//// var /*obj2*/obj2 = {/*name2*/name2, /*id2*/id2};
goTo.marker("obj1");
verify.quickInfoIs("(var) obj1: {\n name1: any;\n id1: any;\n}");
goTo.marker("name1");
verify.quickInfoIs("(property) name1: any");
goTo.marker("id1");
verify.quickInfoIs("(property) id1: any");
goTo.marker("obj2");
verify.quickInfoIs("(var) obj2: {\n name2: string;\n id2: number;\n}");
goTo.marker("name2");
verify.quickInfoIs("(property) name2: string");
goTo.marker("id2");
verify.quickInfoIs("(property) id2: number");
+1 -1
View File
@@ -4,4 +4,4 @@
goTo.eof();
edit.insert(';');
verify.currentLineContentIs('function of1 (b:{ r:{ c: number;');
verify.currentLineContentIs('function of1(b: { r: { c: number;');
@@ -12,11 +12,11 @@ goTo.marker("innermost");
edit.insert(";");
// Adding smicolon should format the innermost statement
verify.currentLineContentIs(' var x = 0;');
verify.currentLineContentIs(' var x = 0;');
// Also should format any parent statement that is terminated by the semicolon
goTo.marker("directParent");
verify.currentLineContentIs(' if (true)');
verify.currentLineContentIs(' if (true)');
// But not parents that are not terminated by it
goTo.marker("parentOutsideBlock");
@@ -0,0 +1,12 @@
/// <reference path='fourslash.ts'/>
////module My.App {
//// export var appModule = angular.module("app", [
//// ]).config([() => {
//// configureStates/*1*/($stateProvider);
//// }]).run(My.App.setup);
////}
goTo.marker("1")
edit.insert("\n");
verify.indentationIs(12); // 4 (module block) + 4 (function block) + 4 (call expression)
@@ -0,0 +1,8 @@
/// <reference path='fourslash.ts'/>
////foo(function () {
////}).then(function () {/*1*/
////})
goTo.marker("1");
edit.insert("\r\n");
verify.indentationIs(4);
@@ -5,8 +5,8 @@ describe("DocumentRegistry", () => {
var documentRegistry = ts.createDocumentRegistry();
var defaultCompilerOptions = ts.getDefaultCompilerOptions();
var f1 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false);
var f2 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false);
var f1 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false);
var f2 = documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false);
assert(f1 === f2, "DocumentRegistry should return the same document for the same name");
});
@@ -17,21 +17,21 @@ describe("DocumentRegistry", () => {
// change compilation setting that doesn't affect parsing - should have the same document
compilerOptions.declaration = true;
var f1 = documentRegistry.acquireDocument("file1.ts", compilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false);
var f1 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false);
compilerOptions.declaration = false;
var f2 = documentRegistry.acquireDocument("file1.ts", compilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false);
var f2 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false);
assert(f1 === f2, "Expected to have the same document instance");
// change value of compilation setting that is used during production of AST - new document is required
compilerOptions.target = ts.ScriptTarget.ES3;
var f3 = documentRegistry.acquireDocument("file1.ts", compilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false);
var f3 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false);
assert(f1 !== f3, "Changed target: Expected to have different instances of document");
compilerOptions.module = ts.ModuleKind.CommonJS;
var f4 = documentRegistry.acquireDocument("file1.ts", compilerOptions, TypeScript.ScriptSnapshot.fromString("var x = 1;"), "1", false);
var f4 = documentRegistry.acquireDocument("file1.ts", compilerOptions, ts.ScriptSnapshot.fromString("var x = 1;"), "1", false);
assert(f1 !== f4, "Changed module: Expected to have different instances of document");
});