Notes
- Typescript transpiles .ts in to .js
- If it finds type errors in code, the code will still be compiled (so long as
the code would otherwise be valid JS).
Types
Array of Numbers
var myArray : number[];
// Works
myArray = [1, 2];
// Does not work
myArray = ['2'];
Array of Multiple Data Types (Tuple)
Array of multiple data types is called a tuple.
- Tuple sizes must match.
var myArray : [number, boolean];
// Works
myArray = [1, true];
// Does not work
myArray = [2];
Return type
let test = (arg1, arg2) : boolean => {
return true;
}
Optional function arguments
// Optional argument 'b'
let test = (a, b?) => {
}
// Optional argument 'b'
let test = (a, b = null) => {
}
// Optional argument 'b' (must be boolean if provided)
let test = (a, b?: boolean) => {
}
Implicit Typing
- Variables are only typed automatically (implicitly) when the assignment
contains a value
// Will result in an error because a has been implicitly typed to number
var a = 1;
a = false;
// Will work because assignment contains no assignemnt
var b;
b = 1;
b = 'hello';
‘any’ Datatype
let test : any;
test = 5;
test = false;
Union Type
let test : number | string;
test = 1;
test = 'test123';
Classes
Declare variable to only be of type
class Employee {
public firstName;
public lastName;
}
// Only type 'Employee' allowed
var employee : Employee;
employee = new Employee();
Inheritance
class Person {
public firstName: string;
public lastName: string;
greet() {
console.log('Hi.');
}
}
class Programmer {
greet() {
console.log('Hello.');
}
greetParent() {
// Uses the parent class (Person) greet function
super.greet();
}
}
// This will work because Programmer extends Person
let programmer : Person = new Programmer();
programmer.greet();
Interfaces and Duck Typing
If it looks like a duck, and quacks like a duck: it is a duck.
- Objects which don’t explicitly implement an interface can still be treated
as an implementation of the interface if it satisfies the relevant conditions.
interface Person {
// Members
public firstName: string;
public lastName: string;
// Returns string
getFullName(): string;
}
// Can use interface in class declaration
class ArbitraryClass implements Person {
public firstName;
public lastName;
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
/**
* Example 1
* Demonstrate duck typing
*/
let arbitraryPersonVariable : Person;
// Can use interface in variable declaration
let arbitraryObject = {
firstName: 'Test',
lastName: 'Tester',
getFullName: () => 'Test full name function.'
}
// This variable can be set to this object through duck typing
arbitraryPersonVariable = arbitraryObject;
/**
* Example 2
* Attempting to access an object member not defined in the iterface
* it implements will result in an error, even if the
*/
let arbitraryPersonVariable2 : Person;
// Can use interface in variable declaration
let arbitraryObject2 = {
firstName: 'Test',
lastName: 'Tester',
getFullName: () => 'Test full name function.',
foo: 'bar'
}
// This will result in error (see block comment)
console.log(arbitraryObject2.foo);
Class Member Visibility
- We can specify the visibility in constructor
- This will automatically set the values
class Person {
constructor(private firstName: string, private lastName: string) {}
}
Readonly Class Members
class Test {
public readonly member;
// Can write to member here
constructor(member) {
this.member = 'Works';
}
}
// We can call constructor to write value
const test = new Test('aaa');
// Error
Test.member = 'Hello.';
Enums (Enumerations)
- Creates constant values for numbers from 0 – length of constants (minus 1)
enum DaysOfWeek {
MON, TUE, WED, THU, FRI, SAT, SUN
}
let day: DaysOfWeek;
day = DaysOfWeek.SAT;
// Can be compared (basically just checking if 5 === 5)
if(day === DaysOfWeek.SAT) {
// Success
console.log('Saturday');
}
enum DaysOfWeek {
MON = 100, TUE
}
if(DaysOfWeek.MON == 100) {
// true
console.log('Monday is 100');
}
Generics
Function example
let getArg = (arg: any) : any => arg;
// If the return type is always the same as the arg passed in then write as
let getArg = (arg: T) : T => arg;
What if we need to ensure generic type is of a child class (rather than a
parent?)
class Person {
public firstName: string;
public lastName: string;
}
class Child implements Person {
}
// We lose information on the datatype if we use the below
function getPersonArg<T>(person: T) : T {
return person;
}
// If we use this function then we retain type information
// Can be any type as long as the type is an instance of Person,
function getPersonArg<T extends Person>(person: T) : T {
return person;
}