installing types
sudo npm install typings --global typings install --save --global dt~underscore typings install --save --global dt~jquery typings install --save --global dt~backbone typings install --save --global dt~moment typings install --save --global dt~qunit typings install --save --global dt~sprintf typings update # than include the file .d.ts
installing libs
bower install jquery bower install underscore
the base lib:
locate lib.d.ts
/usr/local/lib/node_modules/typescript/lib/lib.d.ts
/usr/lib/node_modules/typescript/lib/lib.d.ts
lint:
npm install -g tslint curl https://github.com/palantir/tslint/blob/master/docs/sample.tslint.json > ~/.tslint.json
any void string number boolean
Named types (interface, class, enum)
interface IChild extends IParent, SomeClass { property:Type; optionalProp?:Type; optionalMethod?(arg1:Type):ReturnType; } class Child extends Parent implements IChild, IOtherChild { property:Type; defaultProperty:Type = 'default value'; private _privateProperty:Type; static staticProperty:Type; constructor(arg1:Type) { super(arg1); } private _privateMethod():Type {} methodProperty:(arg1:Type) => ReturnType; overloadedMethod(arg1:Type):ReturnType; overloadedMethod(arg1:OtherType):ReturnType; overloadedMethod(arg1:CommonT):CommonReturnT {} static staticMethod():ReturnType {} subclassedMethod(arg1:Type):ReturnType { super.subclassedMethod(arg1); } } enum Options { FIRST, EXPLICIT = 1, BOOLEAN = Options.FIRST | Options.EXPLICIT }
Object type literals
// Object with implicit Any properties { foo; bar; } // Object with optional property { required:Type; optional?:Type; } // Hash map { [key:string]:Type; }
Hash Maps
var map: { [email: string]: Customer; } = { }; map['foo@gmail.com'] = new Customer(); // OK map[14] = new Customer(); // Not OK, 14 is not a string map['bar@hotmail.com'] = 'x'; // Not OK, x is not a customer You can also make an interface if you don't want to type that whole type annotation out every time: // Equivalent to first line of above interface StringToCustomerMap { [email: string]: Customer; } var map: StringToCustomerMap = { }; // using generic interface in methods signature interface IMap { [key:string] : any; }
Contructors
constructor(public customerId:number,public companyName:string,public country:string) {}
Arrays
// Array of strings string[] Array<string> // Array of functions that return strings { ():string; }[] Array<() => string>
Function Overloading
addCustomer(custId: number); addCustomer(company:string); addCustomer(value: any) { if (value && typeof value == "number") { alert("First overload - " + value); } if (value && typeof value == "string") { alert("Second overload - " + value); } } interface IFoo { bar: { (s: string): number; (n: number): string; } }
Functions
// Function { (arg1:Type, argN:Type):Type; } (arg1:Type, argN:Type) => Type; // Constructor { new ():ConstructedType; } new () => ConstructedType; // Function type with optional param (arg1:Type, optional?:Type) => ReturnType // Function type with rest param (arg1:Type, ...allOtherArgs:Type[]) => ReturnType // Function type with static property { ():Type; staticProp:Type; } //Default argument function fn(arg1:Type = 'default'):ReturnType {} // Arrow function (arg1:Type):ReturnType => {} (arg1:Type):ReturnType => Expression
example anonimous callback
fe.createWriter( (fw: any) => { fw.onwriteend = (e) => { fw.onwriteend = (e) => { callback(); } fw.write(data); } // write BOM (dead for now) fw.write(""); }, (error: any) => { alert("FileWriter Failed: " + error.code); });
Modules
module Company { class Employee { } class EmployeeHelper { targetEmployee: Employee; } export class Customer { } } var obj = new Company.Customer();
Generics
// Generic functions example function reverse<T>(list: T[]): T[] { var reversedList: T[] = []; for (var i = (list.length - 1); i >=0; i--) { reversedList.push(list[i]); } return reversedList; } var letters = ['a', 'b', 'c', 'd']; var reversedLetters = reverse<string>(letters); // d, c, b, a var numbers = [1, 2, 3, 4]; var reversedNumbers = reverse<number>(numbers); // 4, 3, 2, 1
// Function using type parameters function myFunction<T>(items:T[], callback:(item:T) => T):T[] { } class { inArray<T>(value: T, array: T[], fromIndex?: number): number; } interface ITest { data<T>(element: Element, key: string, value: T): T; } //Interface with multiple types interface Pair<T1, T2> { first:T1; second:T2; } // Constrained type parameter <T extends ConstrainedType>():T // Type of a variable typeof varName;
tsc --jsx react public/ts/test.tsx # --jsx react => genera javascript corrispondente al markup jsx
error TS2304: Cannot find name 'React'.
import React = __React;
import React = __React; class DemoProps { public name:string; public age:string; } class DemoComponent extends React.Component<DemoProps, any> { private foo:number; constructor(props:DemoProps) { super(props); this.foo = 42; } render() { return ( <div>Hello world! {this.props.name} </div> ); } } declare var mountNode: any; //React.render(<HelloMessage name="John" />, mountNode); React.render(<DemoComponent name="John" age="21" />, mountNode);
```ts // JavaScript const a = 1 const b = 'foo' const c = true
// TypeScript const a: number = 1 const b: string = 'foo' const c: boolean = true ```
```ts // JavaScript const double = n => 2 * n const sum = a => b => a + b
// TypeScript const double = (n: number): number => 2 * n const sum = (a: number) => (b: number): number => a + b ```
Le funzioni possono essere parametriche
```ts qui il type parameter `A` cattura il fatto che il tipo dell'output deve essere uguale a quello dell'input const identity = (a: A): A => a
qui il type parameter `A` cattura il fatto che il tipo degli elementi dell'array `xs` e quello del valore `x` devono essere uguali const push = (xs: Array, x: A): Array => { const ys = xs.slice() ys.push(x) return ys } ```
```ts JavaScript const a = [1, 2, 3] un array di numeri con lunghezza indefinita const b = [1, 'foo'] // un array con esattamente due elementi, il primo è un numero il secondo una stringa
// TypeScript
const a: Array
```ts // modella un oggetto con due proprietà `x`, `y` di tipo numerico interface Point { x: number y: number }
// le interfacce possono essere estese interface Point3D extends Point { z: number }
le interfacce possono essere parametriche Pair modella un oggetto con due proprietà `x`, `y` // il cui tipo non è ancora precisato ma che deve essere uguale interface Pair { x: A y: A }
questa deifnizione di Point è dunque equivalente
a quella iniziale
interface Point extends Pair
```ts // JavaScript class Person { constructor(name, age) { this.name = name this.age = age } }
// TypeScript class Person { name: string age: number constructor(name: string, age: number) { this.name = name this.age = age } }
// le classi possono essere parametriche class Pair { x: A y: A constructor(x: A, y: A) { this.x = x this.y = y } }
new Pair(1, 2) ok new Pair(1, 'foo') error ```
Per questioni di comodità possiamo dare degli alias ai tipi
```ts Querystring modella i parametri di una querystring come un array di coppie nome / valore type Querystring = Array<[string, string]>
// la querystring `a=foo&b=bar` const querystring: Querystring = 'a', 'foo'], ['b', 'bar'
i type alias possono essere parametrici Pair modella un array con esattamente due elementi // dello stesso tipo type Pair = [A, A] ```
```ts // è possibile definire delle unioni type StringOrNumber = string | number
e delle unioni con discriminante, ovvero una unione di insiemi disgiunti in cui un campo fa da discriminante type Action = { type: 'INCREMENT' } | { type: 'DECREMENT' } ```