2014-08-15 23:33:16 +02:00
=== tests/cases/conformance/functions/functionImplementations.ts ===
// FunctionExpression with no return type annotation and no return statement returns void
var v: void = function () { } ();
>v : void
>function () { } () : void
>function () { } : () => void
// FunctionExpression f with no return type annotation and directly references f in its body returns any
var a: any = function f() {
>a : any
2014-08-22 03:39:46 +02:00
>function f() { return f;} : () => any
2014-08-18 20:10:33 +02:00
>f : () => any
2014-08-15 23:33:16 +02:00
return f;
2014-08-18 20:10:33 +02:00
>f : () => any
2014-08-15 23:33:16 +02:00
};
var a: any = function f() {
>a : any
2014-08-22 03:39:46 +02:00
>function f() { return f();} : () => any
2014-08-15 23:33:16 +02:00
>f : () => any
return f();
>f() : any
>f : () => any
};
// FunctionExpression f with no return type annotation and indirectly references f in its body returns any
var a: any = function f() {
>a : any
2014-08-22 03:39:46 +02:00
>function f() { var x = f; return x;} : () => any
2014-08-18 20:10:33 +02:00
>f : () => any
2014-08-15 23:33:16 +02:00
var x = f;
2014-08-18 20:10:33 +02:00
>x : () => any
>f : () => any
2014-08-15 23:33:16 +02:00
return x;
2014-08-18 20:10:33 +02:00
>x : () => any
2014-08-15 23:33:16 +02:00
};
// Two mutually recursive function implementations with no return type annotations
function rec1() {
2014-08-28 21:52:44 +02:00
>rec1 : () => any
2014-08-15 23:33:16 +02:00
return rec2();
>rec2() : any
2014-08-28 21:52:44 +02:00
>rec2 : () => any
2014-08-15 23:33:16 +02:00
}
function rec2() {
2014-08-28 21:52:44 +02:00
>rec2 : () => any
2014-08-15 23:33:16 +02:00
return rec1();
>rec1() : any
2014-08-28 21:52:44 +02:00
>rec1 : () => any
2014-08-15 23:33:16 +02:00
}
var a = rec1();
>a : any
>rec1() : any
2014-08-28 21:52:44 +02:00
>rec1 : () => any
2014-08-15 23:33:16 +02:00
var a = rec2();
>a : any
>rec2() : any
2014-08-28 21:52:44 +02:00
>rec2 : () => any
2014-08-15 23:33:16 +02:00
// Two mutually recursive function implementations with return type annotation in one
function rec3(): number {
2014-08-28 21:52:44 +02:00
>rec3 : () => number
2014-08-15 23:33:16 +02:00
return rec4();
>rec4() : number
2014-08-28 21:52:44 +02:00
>rec4 : () => number
2014-08-15 23:33:16 +02:00
}
function rec4() {
2014-08-28 21:52:44 +02:00
>rec4 : () => number
2014-08-15 23:33:16 +02:00
return rec3();
>rec3() : number
2014-08-28 21:52:44 +02:00
>rec3 : () => number
2014-08-15 23:33:16 +02:00
}
var n: number;
>n : number
var n = rec3();
>n : number
>rec3() : number
2014-08-28 21:52:44 +02:00
>rec3 : () => number
2014-08-15 23:33:16 +02:00
var n = rec4();
>n : number
>rec4() : number
2014-08-28 21:52:44 +02:00
>rec4 : () => number
2014-08-15 23:33:16 +02:00
// FunctionExpression with no return type annotation and returns a number
var n = function () {
>n : number
2014-08-22 03:39:46 +02:00
>function () { return 3;} () : number
>function () { return 3;} : () => number
2014-08-15 23:33:16 +02:00
return 3;
} ();
// FunctionExpression with no return type annotation and returns null
var nu = null;
>nu : any
var nu = function () {
>nu : any
2014-08-22 03:39:46 +02:00
>function () { return null;} () : any
>function () { return null;} : () => any
2014-08-15 23:33:16 +02:00
return null;
} ();
// FunctionExpression with no return type annotation and returns undefined
var un = undefined;
>un : any
>undefined : undefined
var un = function () {
>un : any
2014-08-22 03:39:46 +02:00
>function () { return undefined;} () : any
>function () { return undefined;} : () => any
2014-08-15 23:33:16 +02:00
return undefined;
>undefined : undefined
} ();
// FunctionExpression with no return type annotation and returns a type parameter type
var n = function <T>(x: T) {
>n : number
2014-08-22 03:39:46 +02:00
>function <T>(x: T) { return x;} (4) : number
>function <T>(x: T) { return x;} : <T>(x: T) => T
2014-08-15 23:33:16 +02:00
>T : T
>x : T
>T : T
return x;
>x : T
} (4);
// FunctionExpression with no return type annotation and returns a constrained type parameter type
var n = function <T extends {}>(x: T) {
>n : number
2014-08-22 03:39:46 +02:00
>function <T extends {}>(x: T) { return x;} (4) : number
>function <T extends {}>(x: T) { return x;} : <T extends {}>(x: T) => T
2014-08-15 23:33:16 +02:00
>T : T
>x : T
>T : T
return x;
>x : T
} (4);
// FunctionExpression with no return type annotation with multiple return statements with identical types
var n = function () {
>n : number
2014-08-22 03:39:46 +02:00
>function () { return 3; return 5;}() : number
>function () { return 3; return 5;} : () => number
2014-08-15 23:33:16 +02:00
return 3;
return 5;
}();
2014-11-05 01:40:56 +01:00
// Otherwise, the inferred return type is the first of the types of the return statement expressions
// in the function body that is a supertype of each of the others,
// ignoring return statements with no expressions.
// A compile - time error occurs if no return statement expression has a type that is a supertype of each of the others.
2014-08-15 23:33:16 +02:00
// FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns
class Base { private m; }
>Base : Base
>m : any
class Derived extends Base { private q; }
>Derived : Derived
>Base : Base
>q : any
var b: Base;
>b : Base
>Base : Base
var b = function () {
>b : Base
2014-08-22 03:39:46 +02:00
>function () { return new Base(); return new Derived();} () : Base
>function () { return new Base(); return new Derived();} : () => Base
2014-08-15 23:33:16 +02:00
return new Base(); return new Derived();
>new Base() : Base
>Base : typeof Base
>new Derived() : Derived
>Derived : typeof Derived
} ();
// FunctionExpression with no return type annotation with multiple return statements with one a recursive call
var a = function f() {
>a : any
2014-08-22 03:39:46 +02:00
>function f() { return new Base(); return new Derived(); return f(); // ?} () : any
>function f() { return new Base(); return new Derived(); return f(); // ?} : () => any
2014-08-15 23:33:16 +02:00
>f : () => any
return new Base(); return new Derived(); return f(); // ?
>new Base() : Base
>Base : typeof Base
>new Derived() : Derived
>Derived : typeof Derived
>f() : any
>f : () => any
} ();
// FunctionExpression with non -void return type annotation with a single throw statement
undefined === function (): number {
2014-08-22 03:39:46 +02:00
>undefined === function (): number { throw undefined;} : boolean
2014-08-15 23:33:16 +02:00
>undefined : undefined
2014-08-22 03:39:46 +02:00
>function (): number { throw undefined;} : () => number
2014-08-15 23:33:16 +02:00
throw undefined;
>undefined : undefined
};
// Type of 'this' in function implementation is 'any'
function thisFunc() {
2014-08-28 21:52:44 +02:00
>thisFunc : () => void
2014-08-15 23:33:16 +02:00
var x = this;
>x : any
>this : any
var x: any;
>x : any
}
// Function signature with optional parameter, no type annotation and initializer has initializer's type
function opt1(n = 4) {
2014-08-28 21:52:44 +02:00
>opt1 : (n?: number) => void
2014-08-15 23:33:16 +02:00
>n : number
var m = n;
>m : number
>n : number
var m: number;
>m : number
}
// Function signature with optional parameter, no type annotation and initializer has initializer's widened type
function opt2(n = { x: null, y: undefined }) {
2014-08-28 21:52:44 +02:00
>opt2 : (n?: { x: any; y: any; }) => void
2014-08-15 23:33:16 +02:00
>n : { x: any; y: any; }
>{ x: null, y: undefined } : { x: null; y: undefined; }
2014-09-10 21:58:30 +02:00
>x : null
>y : undefined
2014-08-15 23:33:16 +02:00
>undefined : undefined
var m = n;
>m : { x: any; y: any; }
>n : { x: any; y: any; }
var m: { x: any; y: any };
>m : { x: any; y: any; }
>x : any
>y : any
}
// Function signature with initializer referencing other parameter to the left
function opt3(n: number, m = n) {
2014-08-28 21:52:44 +02:00
>opt3 : (n: number, m?: number) => void
2014-08-15 23:33:16 +02:00
>n : number
>m : number
>n : number
var y = m;
>y : number
>m : number
var y: number;
>y : number
}
// Function signature with optional parameter has correct codegen
// (tested above)
// FunctionExpression with non -void return type annotation return with no expression
function f6(): number {
2014-08-28 21:52:44 +02:00
>f6 : () => number
2014-08-15 23:33:16 +02:00
return;
}
2014-11-05 01:40:56 +01:00
class Derived2 extends Base { private r: string; }
>Derived2 : Derived2
>Base : Base
>r : string
class AnotherClass { private x }
>AnotherClass : AnotherClass
>x : any
// if f is a contextually typed function expression, the inferred return type is the union type
// of the types of the return statement expressions in the function body,
// ignoring return statements with no expressions.
var f7: (x: number) => string | number = x => { // should be (x: number) => number | string
>f7 : (x: number) => string | number
>x : number
>x => { // should be (x: number) => number | string if (x < 0) { return x; } return x.toString();} : (x: number) => string | number
>x : number
if (x < 0) { return x; }
>x < 0 : boolean
>x : number
>x : number
return x.toString();
>x.toString() : string
>x.toString : (radix?: number) => string
>x : number
>toString : (radix?: number) => string
}
var f8: (x: number) => any = x => { // should be (x: number) => Base
>f8 : (x: number) => any
>x : number
>x => { // should be (x: number) => Base return new Base(); return new Derived2();} : (x: number) => Base
>x : number
return new Base();
>new Base() : Base
>Base : typeof Base
return new Derived2();
>new Derived2() : Derived2
>Derived2 : typeof Derived2
}
var f9: (x: number) => any = x => { // should be (x: number) => Base
>f9 : (x: number) => any
>x : number
>x => { // should be (x: number) => Base return new Base(); return new Derived(); return new Derived2();} : (x: number) => Base
>x : number
return new Base();
>new Base() : Base
>Base : typeof Base
return new Derived();
>new Derived() : Derived
>Derived : typeof Derived
return new Derived2();
>new Derived2() : Derived2
>Derived2 : typeof Derived2
}
var f10: (x: number) => any = x => { // should be (x: number) => Derived | Derived1
>f10 : (x: number) => any
>x : number
>x => { // should be (x: number) => Derived | Derived1 return new Derived(); return new Derived2();} : (x: number) => Derived | Derived2
>x : number
2014-08-15 23:33:16 +02:00
2014-11-05 01:40:56 +01:00
return new Derived();
>new Derived() : Derived
>Derived : typeof Derived
2014-08-15 23:33:16 +02:00
2014-11-05 01:40:56 +01:00
return new Derived2();
>new Derived2() : Derived2
>Derived2 : typeof Derived2
}
var f11: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass
>f11 : (x: number) => any
>x : number
>x => { // should be (x: number) => Base | AnotherClass return new Base(); return new AnotherClass();} : (x: number) => Base | AnotherClass
>x : number
2014-08-15 23:33:16 +02:00
2014-11-05 01:40:56 +01:00
return new Base();
>new Base() : Base
>Base : typeof Base
return new AnotherClass();
>new AnotherClass() : AnotherClass
>AnotherClass : typeof AnotherClass
}
var f12: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass
>f12 : (x: number) => any
>x : number
>x => { // should be (x: number) => Base | AnotherClass return new Base(); return; // should be ignored return new AnotherClass();} : (x: number) => Base | AnotherClass
>x : number
return new Base();
>new Base() : Base
>Base : typeof Base
return; // should be ignored
return new AnotherClass();
>new AnotherClass() : AnotherClass
>AnotherClass : typeof AnotherClass
}