TypeScript

6     Functions

TypeScript extends JavaScript functions to include type parameters, parameter and return type annotations, overloads, default parameter values, and rest parameters.

6.1    Function Declarations

Function declarations consist of an optional set of function overloads followed by an actual function implementation.

FunctionDeclaration:  ( Modified )
FunctionOverloadsopt   FunctionImplementation

FunctionOverloads:
FunctionOverload
FunctionOverloads   FunctionOverload

FunctionOverload:
function   Identifier   CallSignature   ;

FunctionImplementation:
function   Identifier   CallSignature   {   FunctionBody   }

A function declaration introduces a function with the given name in the containing declaration space. Function overloads, if present, must specify the same name as the function implementation. If a function declaration includes overloads, the overloads determine the call signatures of the type given to the function object and the function implementation signature must be assignable to that type. Otherwise, the function implementation itself determines the call signature. Function overloads have no other effect on a function declaration.

6.2    Function Overloads

Function overloads allow a more accurate specification of the patterns of invocation supported by a function than is possible with a single signature. The compile-time processing of a call to an overloaded function chooses the best candidate overload for the particular arguments and the return type of that overload becomes the result type the function call expression. Thus, using overloads it is possible to statically describe the manner in which a function’s return type varies based on its arguments. Overload resolution in function calls is described further in section 4.12.

Function overloads are purely a compile-time construct. They have no impact on the emitted JavaScript and thus no run-time cost.

The parameter list of a function overload cannot specify default values for parameters. In other words, an overload may use only the ? form when specifying optional parameters.

It is an error to declare multiple function overloads that are considered identical (section 3.8.1) or differ only in their return types.

The following is an example of a function with overloads.

function attr(name: string): string;
function attr(name: string, value: string): Accessor;
function attr(map: any): Accessor;
function attr(nameOrMap: any, value?: string): any {
    if (nameOrMap && typeof nameOrMap === "object") {
        // handle map case
    }
    else {
        // handle string case
    }
}

Note that each overload and the final implementation specify the same identifier. The type of the local variable ‘attr’ introduced by this declaration is

var attr: {
    (name: string): string;
    (name: string, value: string): Accessor;
    (map: any): Accessor;
};

Note that the signature of the actual function implementation is not included in the type.

6.3    Function Implementations

A function implementation without a return type annotation is said to be an implicitly typed function. The return type of an implicitly typed function f is inferred from its function body as follows:

·         If there are no return statements with expressions in f’s function body, the inferred return type is Void.

·         Otherwise, if f’s function body directly references f or references any implicitly typed functions that through this same analysis reference f, the inferred return type is Any.

·         Otherwise, the inferred return type is the widened form (section 3.9) of the best common type (section 3.10) of the types of the return statement expression in the function body, ignoring return statements with no expressions. A compile-time error occurs if the best common type isn’t one of the return statement expression types (i.e. if the best common type is an empty type).

TODO: An explicitly typed function returning a non-void type must have at least one return statement somewhere in its body. This rule does not apply if the function implementation consists of a single throw statement.

In the example

function f(x: number) {
    if (x <= 0) return x;
    return g(x);
}

function g(x: number) {
    return f(x - 1);
}

the inferred return type for ‘f’ and ‘g’ is Any because the functions reference themselves through a cycle with no return type annotations. Adding an explicit return type ‘number’ to either breaks the cycle and causes the return type ‘number’ to be inferred for the other.

The type of this in a function implementation is the Any type.

In the signature of a function implementation, a parameter can be marked optional by following it with an initializer. An optional parameter with an initializer but no type annotation has its type inferred from the initializer. Specifically, the type of such a parameter is the widened form of the type of the initializer expression. An initializer expression for a given parameter is permitted to reference parameters that are declared to the left of that parameter, but it is a compile-time error to access other parameters or locals. For each parameter with an initializer, a statement that substitutes the default value for an omitted argument is included in the generated JavaScript, as described in section 6.3. The example

function strange(x: number, y = x * 2, z = x + y) {
    return z;
}

generates JavaScript that is equivalent to

function strange(x, y, z) {
    if (typeof y === "undefined") { y = x * 2; }
    if (typeof z === "undefined") { z = x + y; }
    return z;
}

6.4    Generic Functions

A function implementation may include type parameters in its signature (section 3.7.2.1) and is then called a generic function. Type parameters provide a mechanism for expressing relationships between parameter and return types in call operations. Type parameters have no run-time representation—they are purely a compile-time construct.

Type parameters declared in the signature of a function implementation are in scope in the signature and body of that function implementation.

The following is an example of a generic function:

interface Comparable<T> {
    localeCompare(other: T): number;
}

function compare<T extends Comparable<T>>(x: T, y: T): number {
    if (x == null) return y == null ? 0 : -1;
    if (y == null) return 1;
    return x.localeCompare(y);
}

Note that the ‘x’ and ‘y’ parameters are known to be subtypes of the constraint ‘Comparable<T>’ and therefore have a ‘compareTo’ member. This is described further in section 3.4.

The type arguments of a call to a generic function may be explicitly specified in a call operation or may, when possible, be inferred (section 4.12.2) from the types of the regular arguments in the call. In the example

class Person {
    name: string;
    localeCompare(other: Person) {
        return compare(this.name, other.name);
    }
}

the type argument to ‘compare’ is automatically inferred to be the String type because the two arguments are strings.

6.5    Code Generation

A function declaration generates JavaScript code that is equivalent to:

function <FunctionName>(<FunctionParameters>) {
    
<DefaultValueAssignments>
    
<FunctionStatements>
}

FunctionName is the name of the function (or nothing in the case of a function expression).

FunctionParameters is a comma separated list of the function’s parameter names.

DefaultValueAssignments is a sequence of default property value assignments, one for each parameter with a default value, in the order they are declared, of the form

if (typeof <Parameter> === "undefined") { <Parameter> = <Default>; }

where Parameter is the parameter name and Default is the default value expression.

FunctionStatements is the code generated for the statements specified in the function body.

 


TypeScript Language Specification (converted to HTML pages by @Bartvds)

Version 0.9.1

August 2013

Microsoft is making this Specification available under the Open Web Foundation Final Specification Agreement  Version 1.0 ('OWF 1.0') as of October 1, 2012. The OWF 1.0 is available at  http://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0.

TypeScript is a trademark of Microsoft Corporation.