Skip to content

Latest commit

 

History

History
162 lines (113 loc) · 6.13 KB

ch05.md

File metadata and controls

162 lines (113 loc) · 6.13 KB

5 Statements

This chapter describes the static type checking TypeScript provides for JavaScript statements. TypeScript itself does not introduce any new statement constructs.

5.1 Variable Statements

Variable statements are extended to include optional type annotations.

VariableDeclaration: ( Modified )
    Identifier TypeAnnotation(opt) Initialiser(opt)

VariableDeclarationNoIn: ( Modified )
    Identifier TypeAnnotation(opt) InitialiserNoIn(opt)

TypeAnnotation:
    : Type

A variable declaration introduces a variable with the given name in the containing declaration space. The type associated with a variable is determined as follows:

  • If the declaration includes a type annotation, the stated type becomes the type of the variable. If an initializer is present, the initializer expression is contextually typed (section 4.19) by the stated type and must be assignable to the stated type, or otherwise a compile-time error occurs.
  • If the declaration includes an initializer but no type annotation, and if the initializer doesn't directly or indirectly reference the variable, the widened type (section 3.9) of the initializer expression becomes the type of the variable. If the initializer directly or indirectly references the variable, the type of the variable becomes the Any type.
  • If the declaration includes neither a type annotation nor an initializer, the type of the variable becomes the Any type.

Multiple declarations for the same variable name in the same declaration space are permitted, provided that each declaration associates the same type with the variable.

Below are some examples of variable declarations and their associated types.

var a;                          // any
var b: number;                  // number
var c = 1;                      // number
var d = { x: 1, y: "hello" };   // { x: number; y: string; }
var e: any = "test";            // any

The following is permitted because all declarations of the single variable x associate the same type (Number) with x.

var x = 1;
var x: number;
if (x == 1) {
    var x = 2;
}

In the following example, all five variables are of the same type, { x: number; y: number; }.

interface Point { x: number; y: number; }

var a = { x: 0, y: <number> undefined };
var b: Point = { x: 0, y: undefined };
var c = <Point> { x: 0, y: undefined };
var d: { x: number; y: number; } = { x: 0, y: undefined };
var e = <{ x: number; y: number; }> { x: 0, y: undefined };

5.2 If, Do, and While Statements

Expressions controlling if, do, and while statements can be of any type (and not just type Boolean).

5.3 For Statements

Variable declarations in for statements are extended in the same manner as variable declarations in variable statements (section 5.1).

5.4 For-In Statements

In a for-in statement of the form

for (Var in Expr) Statement

Var must be an expression classified as a reference of type Any or the String primitive type, and Expr must be an expression of type Any, an object type, or a type parameter type.

In a for-in statement of the form

for (var VarDecl in Expr) Statement

VarDecl must be a variable declaration without a type annotation that declares a variable of type Any, and Expr must be an expression of type Any, an object type, or a type parameter type.

5.5 Continue Statements

A continue statement is required to be nested, directly or indirectly (but not crossing function boundaries), within an iteration (do, while, for, or for-in) statement. When a continue statement includes a target label, that target label must appear in the label set of an enclosing (but not crossing function boundaries) iteration statement.

5.6 Break Statements

A break statement is required to be nested, directly or indirectly (but not crossing function boundaries), within an iteration (do, while, for, or for-in) or switch statement. When a break statement includes a target label, that target label must appear in the label set of an enclosing (but not crossing function boundaries) statement.

5.7 Return Statements

It is an error for a return statement to occur outside a function body. Specifically, return statements are not permitted at the global level or in module bodies.

A return statement without an expression returns the value undefined and is permitted in the body of any function, regardless of the return type of the function.

When a return statement includes an expression, if the containing function includes a return type annotation, the return expression is contextually typed (section 4.19) by that return type and must be of a type that is assignable to the return type. Otherwise, if the containing function is contextually typed by a type T, Expr is contextually typed by T's return type.

In a function implementation without a return type annotation, the return type is inferred from the return statements in the function body, as described in section 6.3.

In the example

function f(): (x: string) => number {
    return s => s.length;
}

the arrow expression in the return statement is contextually typed by the return type of f, thus giving type string to s.

5.8 With Statements

Use of the with statement in TypeScript is an error, as is the case in ECMAScript 5's strict mode. Furthermore, within the body of a with statement, TypeScript considers every identifier occurring in an expression (section 4.3) to be of the Any type regardless of its declared type. Because the with statement puts a statically unknown set of identifiers in scope in front of those that are statically known, it is not possible to meaningfully assign a static type to any identifier.

5.9 Switch Statements

In a switch statement, each case expression must be of a type that is assignable to or from (section 3.8.4) the type of the switch expression.

5.10 Throw Statements

The expression specified in a throw statement can be of any type.

5.11 Try Statements

The variable introduced by a catch clause of a try statement is always of type Any. It is not possible to include a type annotation in a catch clause.