Pages

Monday, February 18, 2013

Function-array Type Signature in TypeScript

In TypeScript, a function's type can be specified by a function type literal:

FunctionType:
    ( ParameterListopt ) => ReturnType

For example, the following type signature specifies a unary function that takes a number and returns a number:

var unary: (x: number) => number;

TypeScript also supports array type literals that consist of an element type followed by a pair of brackets:

ArrayType:
    Type [ ]

Now, suppose we need an array of unary functions, what would be the type signature of the function array?

Appending a pair of brackets to the previous function type literal wouldn't work because the resulting type signature, though syntactically correct, defines a single function that returns an array of numbers rather than an array of functions, each returning a single number:

var wrong: (x: number) => number [];

Trying to disambiguate the semantics by wrapping the function type literal in parentheses is also erroneous — the first left parenthesis would be matched as the initial token of a FunctionType rule, therefore the compiler would flag the second left parenthesis as a grammar error:

var wrongToo: ( (x: number) => number ) [];

The key to solving this is the realization that a function type literal of the form ( ParameterListopt ) => ResultType can be rewritten as the equivalent object type literal { ( ParameterListopt ) : ResultType; }, which removes the ambiguity in a function array type signature. For example:

var correct: {(x: number): number;}[];

To improve code readability, we may define a separate type name and reference it in the array type:

interface UnaryFunc {
  (x: number): number;
}

var unaryFuncArray: UnaryFunc[];