TypeScript

JavaScript that scales.

JavaScript that scales.

Example 1

Type inference.

// example.js


function square(n) {
  return n * n;
}

square('2');

Example 1

Type inference.

// example.ts

// function square(n: any): number
function square(n) {
  return n * n;
}

square('2');

Example 1

Type inference.

// example.ts

// function square(n: number): number
function square(n: number): number {
  return n * n;
}

square('2');

Example 1

Type inference.

// example.ts

// function square(n: number): number
function square(n: number): number {
  return n * n;
}

square('2'); // Argument of type '"2"' is not assignable to parameter of type 'number'.

Example 2

Type refinement.

// example.ts

function foo(x): string {
  if (typeof x === 'number') {
    return x;
  }
  return 'default string';
}

Example 2

Type refinement.

// example.ts

function foo(x): string {
  if (typeof x === 'number') {
    return x; // Type 'number' is not assignable to type 'string'.
  }
  return 'default string';
}

Example 3

Nullable & non-nullable types.

// example.ts


function foo(num: number) {
    if (num > 5) {
      return 'cool';
    }
}

const x = foo(9).toString();
const y = foo(1).toString();

Example 3

Nullable & non-nullable types.

// example.ts

// function foo(num: number): string
function foo(num: number) {
    if (num > 5) {
      return 'cool';
    }
}

const x = foo(9).toString();
const y = foo(1).toString();

Example 3

Nullable & non-nullable types.

// example.ts

// function foo(num: number): string
function foo(num: number): string {
    if (num > 5) {
      return 'cool';
    }
}

const x = foo(9).toString();
const y = foo(1).toString();

Example 3

Nullable & non-nullable types.

// example.ts, strictNullChecks

// function foo(num: number): string
function foo(num: number): string { // Function lacks ending return statement
    if (num > 5) {                  // and return type does not include 'undefined'.
      return 'cool';
    }
}

const x = foo(9).toString();
const y = foo(1).toString();

Example 4

Subset types.

// example.ts

type TypeA = 1 | 2;
type TypeB = 1 | 2 | 3;

let x: TypeA = 2;
let y: TypeB = 2;

x = y;
y = x;

Example 4

Subset types.

// example.ts

type TypeA = 1 | 2;
type TypeB = 1 | 2 | 3;

let x: TypeA = 2;
let y: TypeB = 3;

x = y;
y = x;

Example 4

Subset types.

// example.ts

type TypeA = 1 | 2;
type TypeB = 1 | 2 | 3;

let x: TypeA = 2;
let y: TypeB = 3;

x = y; // Type '3' is not assignable to type 'TypeA'.
y = x;

Example 4

Subset types.

// example.ts

type TypeA = 1 | 2;
type TypeB = 1 | 2 | 3;

let x: TypeA;
let y: TypeB;

x = y;
y = x;

Example 4

Subset types.

// example.ts

type TypeA = 1 | 2;
type TypeB = 1 | 2 | 3;

let x: TypeA;
let y: TypeB;

x = y; // Type 'TypeB' is not assignable to type 'TypeA'.
       //   Type '3' is not assignable to type 'TypeA'.
y = x;

Example 5

Subtypes.

// example.ts

interface ObjectA { foo: string }
interface ObjectB { foo: string, bar: number }

let objectB: ObjectB = { foo: 'test', bar: 42 };
let objectA: ObjectA = objectB;

Example 5

Subtypes.

// example.ts

interface ObjectA { foo: string }
interface ObjectB { foo: string, bar: number }

let objectB: ObjectB = { foo: 'test', bar: 42 };
let objectA: ObjectA = objectB;

Example 5

Subtypes.

// example.ts

interface ObjectA { foo: string }
interface ObjectB { foo: string, bar: number }

let objectB: ObjectB = { foo: 'test', bar: 42 };
let objectA: ObjectA = objectB; // Works!

Example 5

Subtypes.

// example.ts

interface ObjectA { foo: number }
interface ObjectB { foo: string, bar: number }

let objectB: ObjectB = { foo: 'test', bar: 42 };
let objectA: ObjectA = objectB;

Example 5

Subtypes.

// example.ts

interface ObjectA { foo: number }
interface ObjectB { foo: string, bar: number }

let objectB: ObjectB = { foo: 'test', bar: 42 };
let objectA: ObjectA = objectB; // Type 'ObjectB' is not assignable to type 'ObjectA'.
                                //   Types of property 'foo' are incompatible.
                                //     Type 'string' is not assignable to type 'number'.

Real life 1

Declaration files

// example.d.ts

export as namespace myLib;

// If this module has methods, declare them as functions like so.
export function myMethod(a: string): string;
export function myOtherMethod(a: number): number;

// You can declare types that are available via importing the module.
export interface someType {
    name: string;
    length: number;
    extras?: string[];
}

// You can declare properties of the module using const, let, or var.
export const myField: number;

// If there are types, properties, or methods inside dotted names
// of the module, declare them inside a 'namespace'.
export namespace subProp {
    export function foo(): void;
}

Real life 1

Declaration files

// shell

npm install @types/moment

Real life 1

Declaration files

// example.ts

import * as moment from 'moment';

function getThing(): moment {
  // ...
}

Real life 2

tsc
// shell

npm install -g typescript
tsc example.ts

Real life 2

tsc
// tsconfig.json

{
  // Trigger an error if TypeScript uses 'any' whenever it can't infer a type.
  "noImplicitAny": true,

  // Makes types non-nullable by default, catching a broad class of errors.
  "strictNullChecks": true,

  // Disable bivariant parameter checking for function types.
  "strictFunctionTypes": true,

  // Ensure non-undefined class properties are initialized in the constructor.
  "strictPropertyInitialization": true,

  // Flag locations where the type of a 'this' expression implicitly has the type 'any'.
  "noImplicitThis": true,

  // Error on functions which do not return from every branch.
  "noImplicitReturns": true,

  // ...
}

Real life 3

tslint
// shell

npm install tslint
tslint --init
tslint **/*.ts

Bonus

@babel-preset-typescript

Links

TypeScript

By Radosław Miernik

TypeScript

Vazco TechMeeting 2018-05-25

  • 698