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' } ```