String
const str: string = 'Some text';
Number
const num: number = 5;
Boolean
const bool: boolean = true;
Array
const strArray1: string[] = ['first', 'second'];
const strArray2: Array<string> = ['first', 'second'];
Tuple
const tuple: [string, number] = ['name', 42];
Any
let randomData: any = 10;
randomData = {}
randomData = 10
Null, Undefined
// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;
Void
// when function returns nothing
function func(error): void {
console.log('logger function', error);
}
func() // returns nothing === void;
Never
// when the execution of the function will never end
function func(err): never {
throw new Error(err);
}
func() // always throws error === never;
Type
type Id = string | number;
const useId: Id = 'sf32sf2edf';
const productId: Id = 235345345;
Readonly,optional
interface Person {
readonly name: string
nickname?: string
age: number
}
// readonly - cannot override the value
// ? - optional property
const user: Person = {
name: 'John',
age: 40,
}
Extending Interfaces
interface Person {
name: string
age: number
}
const user1 = {} as Person
user1.age = 31;
const user2 = <Person>{}
user2.age = 19;
Inheritance
interface Rect {
width: number
height: number
}
interface RectWithMathods extends Rect {
getSquare: () => number
}
const rect1: Rect = {
width: 10,
height: 15,
}
const rect2: Rect = {
width: 13,
height: 12,
getSquare(): number {
return this.width * this.height,
}
}
Inherit class from interface
interface Rect {
width: number
height: number
getSquare: () => number
}
class SmallRect implements Rect {
width: number = 38
height: number = 29
getSquare(): number {
return this.width * this.height,
}
}
Dynamic keys
interface Rect {
width: number
height: number
getSquare: () => number
[key: string]: number
}
// [key: string]: number - dynamic keys with type "number"
enum Options {
Free,
Paid,
Partial = "partial option",
}
const option = Options.Paid // 1, because it's the second item of "array Options"
const optionReverse = Options[0] // "Free"
const optionWithAssignedValue = Options.Partial // "partial option"
function sum(a: number, b: number): number {
return a + b
}
interface MyPosition {
x: number | undefined
y: number | undefined
}
interface MyPositionWithDefault extends MyPosition {
default: string
}
function position(): MyPosition
function position(a: number): MyPositionWithDefault
function position(a: number, b: number): MyPosition
function position(a?: number, b?: number) {
if (!a && !b) {
return {x: undefined, y: undefined}
}
if (a && !b) {
return {x: a, y: undefined, default: a.toString()}
}
return {x: a, y: b}
}
console.log('Empty: ', position())
console.log('One param: ', position(42))
console.log('Two params: ', position(10, 15))
class Typescript {
version: string
constructor(version: string) {
this.version = version
}
info(name: string) {
return `[${name}]: Typescript version is ${this.version}`
}
}
// class Car {
// readonly model: string
// readonly numberOfWheels: number = 4
//
// constructor(theModel: string) {
// this.model = theModel
// }
// }
class Car {
readonly numberOfWheels: number = 4
constructor(readonly model: string) {}
}
Modifiers
public - by default (even if we don't set it explicitly), accessible for the current class, extending classes, instances;
protected - accessible for the current class, extending classes, but not for the instances;
private - accessible only for the current class
class Animal {
protected voice: string = ''
public color: string = 'black'
constructor() {
this.go()
}
private go() {
console.log('Go')
}
}
class Cat extends Animal {
public setVoice(voice: string): void {
this.voice = voice
}
}
const cat = new Cat()
cat.setVoice('test')
console.log(cat.color)
// cat.voice
Abstract class
abstract class Component {
abstract render(): void
abstract info(): string
}
class AppComponent extends Component {
render(): void {
console.log('Component on render')
}
info(): string {
return 'This is info';
}
}
const arrayOfNumbers: Array<number> = [1, 1, 2, 3, 5]
const arrayOfStrings: Array<string> = ['Name', 'Surname']
function reverse<T>(array: T[]): T[] {
return array.reverse()
}
reverse(arrayOfNumbers)
reverse(arrayOfStrings)
interface Person {
name: string
age: number
}
type PersonKeys = keyof Person // 'name' | 'age'
let key: PersonKeys = 'name'
key = 'age'
type User = {
_id: number
name: string
email: string
createdAt: Date
}
type UserKeysNoMeta1 = Exclude<keyof User, '_id' | 'createdAt'> // 'name' | 'email'
type UserKeysNoMeta2 = Pick<User, 'name' | 'email'> // 'name' | 'email'
let u1: UserKeysNoMeta1 = 'name'
// u1 = '_id'