March 2017, Nejc Zdovc
workshop #2
TypeScript
Config
@types
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"noImplicitAny": true,
"preserveConstEnums": true,
"outDir": "./dist",
"sourceMap": true
},
"include": [
"**/*.ts"
],
"exclude": [
"node_modules"
]
}
tsconfig.json
Types
Enum
Interface
Function
Classes
Generics
Modules
// boolean
let isDone: boolean = false;
// number
let grade: number = 6;
let score: number = 6.6;
// string
let color: string = "blue";
// tuple (array with different types)
let x: [string, number];
x = ["hello", 10]; # OK
x = [10, "hello"]; # ERROR
// Any (it's there, but don't use it, because yo would loose a power of TS)
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
let color: number = "blue";
index.ts(1,5): error TS2322: Type '"blue"' is not assignable to type 'number'.
// only numeric constants
enum Color {Red, Green, Blue}; // Red = 1, Green = 2, Blue = 3
enum Color {Red = 1, Green = 2, Blue = 4};
// string literal as an alternative for string enum
type CardinalDirection =
"North"
| "East"
| "South"
| "West";
function move(distance: number, direction: CardinalDirection) {
// ...
}
move(1,"North"); // Okay
move(1,"Nurth"); // Error!
index.ts(12,8): error TS2345: Argument of type '"Nurth"' is not assignable
to parameter of type 'CardinalDirection'.
interface SquareConfig {
color?: string;
opacity?: number;
width: number;
}
function createSquare(config: SquareConfig) {
// some logic
}
// OK
let square1 = createSquare({width: 100})
let square1 = createSquare({width: 100, opacity: 0.6})
let square1 = createSquare({width: 100, opacity: 0.6, color: 'black'})
// ERROR
let square1 = createSquare({opacity: 0.6, color: 'black'})
let square1 = createSquare({width: '100'})
index.ts(17,28): error TS2345: Argument of type '{ opacity: number; color: string; }'
is not assignable to parameter of type 'SquareConfig'.
Property 'width' is missing in type '{ opacity: number; color: string; }'.
index.ts(18,28): error TS2345: Argument of type '{ width: string; }' is not assignable
to parameter of type 'SquareConfig'.
Types of property 'width' are incompatible.
Type 'string' is not assignable to type 'number'.
function addFirst(x: number, y: number): number {
return x + y;
}
function addSecond(x: number, y?: number): number {
if(y !== undefined) {
return x + y;
} else {
return x + x;
}
}
function addThird(x: number, y: number = 15): number {
return x + y;
}
console.log(addFirst(5,10)); // 15
console.log(addSecond(5)); // 10
console.log(addThird(5)); // 20
function sum(x: number | string) {
if(typeof x === 'number') {
return x + x;
} else {
return `${x} and ${x}`;
}
}
console.log(sum(5)) // 10
console.log(sum("yes")) // yes yes
class Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
move(distanceInMeters: number = 0): void {
console.log(`${this.name} moved ${distanceInMeters}m.`);
}
}
class Snake extends Animal {
private color: string;
constructor(name: string, color: string) {
super(name);
this.color = color;
}
move(distanceInMeters: number = 5): void {
console.log("Slithering...");
super.move(distanceInMeters);
}
}
let sam = new Snake("Sammy the Python", "red");
sam.move();
class GenericAdd<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
// numbers
let myGeneric = new GenericAdd<number>();
myGeneric.zeroValue = 0;
myGeneric.add = function(x, y) {
return x + y;
};
console.log(myGeneric.add(5, 10)); // 15
// strings
let stringNumeric = new GenericAdd<string>();
stringNumeric.zeroValue = "yo";
stringNumeric.add = function(x:string, y: string): string {
return x + y;
};
console.log(stringNumeric.add(stringNumeric.zeroValue, "test")); // yotest
console.log(myGeneric.add(5, "tt"));
index.ts(12,30): error TS2345: Argument of type '"tt"' is not assignable
to parameter of type 'number'.
// validator.ts
class Validator {
private numberRegexp: RegExp = /^[0-9]+$/;
isAcceptable(s: string) {
return s.length === 5 && this.numberRegexp.test(s);
}
}
// possible export options
export class Validator {
// rest of the code
}
export { Validator };
export { Validator as mainValidator };
// main.ts
import { validator } from "./validator";
let myValidator = new validator();
// option 1
import { validator as valid } from "./validator";
let myValidator = new valid();
// option 2
import * as foo from "./validator";
let myValidator = new foo.validator();