Control flow based type analysis

TypeScript 2.0 implements a control flow-based type analysis for local variables and parameters.Previously, the type analysis performed for type guards was limited to if statements and ?: conditional expressions and didn’t include effects of assignments and control flow constructs such as return and break statements.With TypeScript 2.0, the type checker analyses all possible flows of control in statements and expressions to produce the most specific type possible (the narrowed type) at any given location for a local variable or parameter that is declared to have a union type.

Example

  1. function foo(x: string | number | boolean) {
  2. if (typeof x === "string") {
  3. x; // type of x is string here
  4. x = 1;
  5. x; // type of x is number here
  6. }
  7. x; // type of x is number | boolean here
  8. }
  9. function bar(x: string | number) {
  10. if (typeof x === "number") {
  11. return;
  12. }
  13. x; // type of x is string here
  14. }

Control flow based type analysis is particuarly relevant in —strictNullChecks mode because nullable types are represented using union types:

  1. function test(x: string | null) {
  2. if (x === null) {
  3. return;
  4. }
  5. x; // type of x is string in remainder of function
  6. }

Furthermore, in —strictNullChecks mode, control flow based type analysis includes definite assignment analysis for local variables of types that don’t permit the value undefined.

  1. function mumble(check: boolean) {
  2. let x: number; // Type doesn't permit undefined
  3. x; // Error, x is undefined
  4. if (check) {
  5. x = 1;
  6. x; // Ok
  7. }
  8. x; // Error, x is possibly undefined
  9. x = 2;
  10. x; // Ok
  11. }