Introduction to TypeScript
by @leocaseiro
What
is
TypeScript?
"Microsoft TypeScript is an open-source programming language developed and maintained by Microsoft. It is a strict syntactical superset of JavaScript, and adds optional static typing to the language."
=
+ types
What
is a
Transpiler?
Compiler vs Transpiler
1100 1010
1010 0101
0101 1100
compile to
transpile to
different level of abstration
same level of abstration
*.ts
*.js
JS data types (shapes)
- null
- undefined
- boolean
- number
- string
- Object
- Array
- Date*
- Symbol (ES6)**
* TypeScript interface (object)
** not covered on this course
type of
typeof "text";
// string
null
undefined
let a = null;
console.log(a);
// null
typeof a;
// 'object' What?
There are two features of null you should understand:
- null is an empty or non-existent value.
- null must be assigned.
Undefined most typically means a variable has been declared, but not defined.
You can also explicitly set a variable to equal undefined:
let b;
console.log(b);
// undefined
var d = {};
console.log(d.fake);
// undefined
var u = undefined;
boolean (binary)
true or false
1 or 0
let a = true;
console.log(a);
// true
let b = 1;
console.log(b);
// 1
console.log(a == b);
// true
console.log(a === b);
// false
let c = false;
console.log(c);
// false
let c = 0;
console.log(d);
// 0
console.log(c == d);
// true
console.log(c === d);
// false
let a = true;
typeof a;
// boolean
let b = 1;
typeof b;
// number
Not the same as truthy and falsy
number
integer, float (decimals)
let a = 123;
typeof a;
// number
let b = 12.3;
typeof b;
// number
console.log(a > b);
// true
let c = "123";
typeof c;
// string
let d = "12.3";
typeof d;
// string
console.log(c > d);
// true
string (text)
anything between quotes (", ', `)
let a = "John";
typeof a;
// string
let b = 'Doe';
typeof b;
// string
console.log(a + b);
// 'JohnDoe'
console.log(a + " " + b);
// 'John Doe'
let a = `John`;
typeof a;
// string
let b = `Doe`;
typeof b;
// string
console.log(`${a} ${b}`);
// 'John Doe'
typeof `123.00`;
// string
` (back-ticks)
object
let person = {
firstName: "John",
lastName: "Doe"
};
typeof person;
// object
typeof person.firstName;
// string
typeof window;
// object
typeof document;
// object
function / class*
function hello(name) {
return `hello ${name}`;
}
typeof hello;
// function
class Calculator {
sum = (a, b) => a + b
}
typeof Calculator;
// function
*syntax sugar for functions
var hello = (name) => {
return `hello ${name}`;
}
typeof hello;
// function
array (collection)
let mixed = Array(1, 2, 'text', {name: 'John'})
// mixed = [1, 2, 'text', {name: 'John'}] // same
typeof mixed
// object
Array.isArray(mixed)
// true
typeof mixed[0];
// number
typeof mixed[2];
// string
typeof mixed[3];
// object
typeof mixed[4];
// undefined
Date (interface)
let bday = new Date(1991, 11, 25);
typeof bday // Object
console.log(bday);
// Wed Dec 25 1991 00:00:00
// GMT+1100 (Australian Eastern Daylight Time)
new Date(year, monthIndex [, day [, hours [, minutes [, seconds [, milliseconds]]]]]);
JavaScript syntax
let user = "John Doe"
declaration
set
value
name
TypeScript syntax
let user: string = "John Doe"
declaration
set
value
name
annotation
type
Let's Play TS
TS "or" syntax
let xyz: number | string = r;
or
type
type
TS Array<T> syntax
const numbers: Array<number> = [1,2,3,4]
const oddNumbers: number[] = [1,3,5,7,9];
Generic Types
-
any
-
<T>
type: any
interface Person {
firstName: string;
}
let user: Person = {
firstName: 'John'
}
user = 'John Doe';
// Type '"John Doe"' is not assignable to type 'Person'.
interface Person {
firstName: string;
}
let user: any = {
firstName: 'John'
}
user = 'John Doe';
--noImplicitAny = false
Generic <T>
function foo(arg: string): string {
return arg;
}
foo('test'); // return string
foo(123);
// Argument of type '123' is not assignable
// to parameter of type 'string'.
function foo<T>(arg: T): T {
return arg;
}
foo('test'); // return string
foo(123); // return number
function foo<T>(list: T[]): T[] {
console.log(list.length);
return list;
}
Exercise 01
5 minutes
npm start
JS function syntax
function sum (n1, n2) {
const r = n1 + n2;
return r;
}
declaration
output
return
arguments
name
TS function syntax
function sum (n1: number, n2: number): number {
const r = n1 + n2;
return r;
}
declaration
output
return
argument
name
argument
arg. type
arg. type
output type
TS arrow function syntax
const greeting = (name: string): string => {
const r = `hello ${name}`;
return r;
}
declaration
output
return
argument
name
output type
argument type
TS void output syntax
const setName = (n: string): void => {
name = n;
}
no output
Exercise 02
10 minutes
npm start
Enums
enum State {
ACT = "Australian Capital Territory",
NSW = "New South Wales",
QLD = "Queensland",
SA = "South Australia",
TAS = "Tasmania",
VIC = "Victoria",
WA = "Western Australia"
}
const myState: State = State.NSW;
console.log(myState);
// New South Wales
Enums
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
var d = Direction.Up;
console.log(d); // 0
enum Direction {
Up = 1, // 1
Down, // 2
Left, // 3
Right // 4
}
var d = Direction.Up;
console.log(d); // 1
Classes
Constructor
class Person {
firstName: string;
lastName: string;
constructor(first: string, last: string) {
this.firstName = first;
this.lastName = last;
}
}
const user = new Person('John', 'Doe');
console.log(user.lastName);
// Doe
class Animal {
move(distanceInMeters: number = 0) {
console.log(`Animal moved ${distanceInMeters}m.`);
}
}
class Dog extends Animal {
bark() {
console.log('Woof! Woof!');
}
}
const dog = new Dog();
dog.bark();
dog.move(10);
dog.bark();
Class Inheritance (extends)
class Animal {
name: string;
constructor(n: string) { this.name = n; }
move(distanceInMeters: number = 0) {
console.log(`moved ${distanceInMeters}m.`);
}
}
class Horse extends Animal {
constructor(name: string) {
super(name);
}
move(distanceInMeters = 45) {
console.log("Galloping...");
super.move(distanceInMeters);
}
}
Class Inheritance (extends, super)
class Person {
private firstName: string;
lastName: number; // public
constructor(first: string, last: string) { ... }
}
const user = new Person('John', 'Doe');
console.log(user.firstName);
// Property 'firstName' is private
// and only accessible within class 'Person'.
public and private
class Person {
private age: number;
protected name: string;
constructor(n: string, a: number) { this.name = n; this.age = a; }
}
class Employee extends Person {
constructor(name: string, age: number) {
super(name, age);
}
getName() {
return `Hello, my name is ${this.name}`;
}
getAge() {
return `Hello, my age is ${this.age}`;
// Property 'age' is private
// and only accessible within class 'Person'.
}
}
private vs protected
class Calendar {
private _month: number;
get month() {
if (this._month != null) {
return this._month;
}
}
set month(m: number) {
if (m > 0 && m < 13) {
this._month = m;
}
}
}
Accessors (get, set)
strictPropertyInitialization = false
typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#strict-class-initialization
Abstract Class / method
abstract class Animal {
move(distanceInMeters: number = 0) {
console.log(`Animal moved ${distanceInMeters}m.`);
}
abstract foo(n: string): string; // like an interface
}
class Dog extends Animal {
bark() {
console.log('Woof! Woof!');
}
foo(n: string) { return n; }
}
const dog = new Dog();
dog.move(5); // inherited
dog.foo('bar'); // class 'Dog' implements inherited
// abstract member 'foo' from class 'Animal'.
Interface
defining contracts
(like a custom type)
Interface Example
interface IPerson {
age?: number;
firstName: string;
lastName: string;
}
let user: IPerson = {
firstName: 'John',
lastName: 'Doe'
};
user.age = 18;
TS interface syntax
interface Person {
firstName: string;
lastName: string;
}
interface
name
property
braces
type
semicolon
(no equal sign)
TS function interface syntax
interface SearchFunc {
(source: string): boolean;
}
parentheses
TS interface usage
interface Person {
firstName: string;
}
let user: Person = {
firstName: 'John'
}
Interface - optional property
interface Person {
firstName: string;
age?: number;
}
const user: Person = {
firstName: 'John'
}
user.age = 18;
optional property
(question mark)
optional property for functions
function setPerson(name: string, age?: number) {
// ...
}
optional property
(question mark)
Interface - readonly property
interface Person {
readonly firstName: string;
}
const user: Person = {
firstName: 'John'
}
user.firstName = 'Jane'; // error*
// Cannot assign to 'firstName' because it is a read-only property.
(like const, but for properties)
Exercise 03
15 minutes
npm start
Some TS tricks
(variable as <T>)
let foo: string = 'John Doe';
foo = 0;
// Type '0' is not assignable to type 'string'.
let foo: string = 'John Doe';
(foo as any) = 123;
// @ts-ignore
if (false) {
// @ts-ignore
console.log("hello");
}
.tsconfig
{
"compilerOptions": {
"outDir": "./built",
"allowJs": true,
"target": "es5"
},
"include": [
"./src/**/*"
]
}
tsc --init
Declaration Types
*.d.ts
TSLint
⚠️ TSLint will be deprecated some time in 2019. See this issue for more details: Roadmap: TSLint → ESLint. If you're interested in helping with the TSLint/ESLint migration, please check out our OSS Fellowship program
TSLint
TSLint + ESLint
Enables ESLint to support TypeScript
Code Analysis
+
Code Style Checker
Exercise 04
cd app;
yarn;
yarn start;
Install TypeScript
npm install typescript
# or
yarn add typescript
Install Declaration Types
npm install @types/node @types/react @types/react-dom
# or
yarn add @types/node @types/react @types/react-dom
Rename any file to be a TypeScript file.
*.js => *.ts
References
References / Images
What next?
Introduction to TypeScript - Muses Code JS
By Leo Caseiro
Introduction to TypeScript - Muses Code JS
- 1,340