Note on Typescript / Typescript 笔记

Posted by Pengyu on January 9, 2024

TypeScript is a superset of JavaScript. As such, a JavaScript program is also a valid TypeScript program and a TypeScript program can seamlessly consume JavaScript.

typescript superset

TS: Strongly Typed Language; Statically typed Language (Checked at compile time) JS: Loosely Typed Language; Dynamically typed Language (Checked at run time)

Hello World

const hello : string = “Hello World!”

let a: string = ‘abc’ let b: number = 123 let c: boolean = true let d: any = ‘’ let re: RegExp = /\w+/g

const sum = (a: number, b: number) => { return a + b; }

Union type

let postId: string number
let isActive: number boolean

let re = /\w+/g

Arrays & Objects

let stringArr = [‘one’,’two’,’three’] // string let guitars = [‘one’,’two’,123] // string | number let mixed = [‘one’,1992,true] // string | number | boolean let empty = [] // any

let bands: stirng[] = [];

// Tuple: exactly number, type and position let myTuple: [stirng, number, boolean]

// Objects

let myObj: object

const exampleObj = { prop1: ‘abc’, prop2: true }

const exampleObj: { prop1: string; prop2: boolean; }

type Guitarist = { name: string, active: boolean, albums: (string | number)[] }

let evh: Guitarist = { name: ‘Chen’, active: false, albums: [1992, 5140, ‘Test’] }

// Enums

enum Grade { U, D, C, B, A }

Grade.U // 0

Functions

// Type Aliases

type stringOrNumber = string number
type stringOrNumberArray = (string number)[]

type Guitarist = { name?: string, active: boolean, albums: (string | number)[] }

type UserId = stringOrNumber

// Literal types

let myName: ‘Chen’ let userName: ‘Chen’ | ‘Li’ | ‘Peng’

// functions

const add = (a: number, b: number) : number => { return a + b; }

const logMsg = (message: any): void => { console.log(message) }

type mathFunction = (a: number, b: number) => number

let multiply: mathFunction = function (c,d) { return c * d }

interface mathFunction { (a: number, b: number): number }

// optional parameters const addAll = (a:number, b:number, c?:number): number => { if(typeof c !== ‘undefined’) { return a + b + c } return a + b }

// Rest parameters

cosnt total = (a: number, …nums: number[]) : number => { return a + nums.reduce((prev, curr) => prev + curr) }

Classes

class Coder { constructor( public readonly name: string, public music:string, private age: number, protected lang: string = ‘Typescript’ ) { this.name: name this.music: music this.age: age this.lang: lang }

public getAge() { return Hello, I'm ${this.age} } }

const Dave = new Coder(‘Dave’, ‘Rock’, 32)

class WebDev extends Coder { constructor( public computer: string, name: string, music:string, age: number,

) { super(name, music, age) this.computer = computer }

public getLang() { return I write ${this.lang} } }

const Sara = new WebDev(‘Mac’, ‘Sara’, ‘Lofi’,25) console.log(Sara.getLang()) // I write Typescript

interface Musician { name: string, instrument: string, play(action: string): string }

class Guitarist implements Musician { name: string instrument: string

constructor(name: string, instrument: string){ this.name = name; this.instrument =instrument }

play(action: string) { return ${this.name} ${action} the ${this.instrument} } }

const Page = new Guitarist(‘Jimmy’, ‘guitar’) conosle.log(Page.play(‘strums’)) // Jimmy strums the guitar

class Peeps { static count: number = 0 static getCount(): number { return Peeps.count }

public id: number construtor(public name: string) { this.name = name this.id = ++Peeps.count } }

const John = new Peeps(‘John’) const Steve = new Peeps(‘Steve’) const Amy = new Peeps(‘Amy’)

class Bands { private dataState: string[]

construtor() { this.dataState = [] }

public get data(): string[] { return this.dataState }

public set data(value: string[]) { if(Array.isArray(value) && value.every(el=>typeof el === ‘string’)) { this.dateState = value return } else throw new Error(‘Param is not an array of strings’)

} }

const MyBands = new Bands() MyBands.data = [‘Neil Young’, ‘Led Zep’]

console.log(MyBands.data) // [‘Neil Young’, ‘Led Zep’] MyBands.data = […MyBands.data, ‘ZZ Top’] console.log(MyBands.data) // [‘Neil Young’, ‘Led Zep’,’ZZ Top’]

Index Signatures & keyof Assertions

// Index Signatures

interface TransactionObj { Pizza: number, Books: number, Job: number }

const todaysTransactions: TransactionObj = { Pizza: -10, Books: -5, Job: 50 }

interface TransactionObj { [index: string]: number }

////////////////

interface Student { [key: string]: string | number | number[] | undefined, name: string, GPA: number, classes?: number[] }

const student: Student = { name: “Dong”, GPA: 3.5, classes: [100, 200] }

for(const key in student) { console.log(${key}: ${student[key as keyof Student]}) }

type Stream = ‘salary’ ‘bouns’ ‘sidehustle’
type Incomes = Record<Streams, number string>

const monthlyIncomes: Incomes = { salary: 500, bonus: 100, sidehustle: 250 }

for(const revenue in monthlyIncomes) { console.log(monthlyIncomes[revenue as keyof Incomes]) }

Generics

const echo = (arg: T): T => arg const isObj = (arg: T): boolean => { return (typeof arg === 'obj' && !Array.isArray(arg) && arg !== null) }

const isTrue = (arg: T): { arg: T, is: boolean} => { if(Array.isArray(arg) && !arg.length) { return {arg, is: false} } if(isObj(arg) && !Object.keys(arg as keyof T).length) { return {art, is: false} } return {arg, is: !!arg}

}

Utility Types

// Partial

interface Assignment { studentId: string, title: string, grade: number, verified?: boolean, }

const updateAssignment = (assign: Assignment, propsToUpdate: Partial): Assignment => { return { ...assign, ...propsToUpdate } }

const assign1: Assignment = { studentId: “compsci123”, title: “Final Project”, grade: 0, }

console.log(updateAssignment(assign1, { grade: 95 })) const assignGraded: Assignment = updateAssignment(assign1, { grade: 95 })

// Required and Readonly

const recordAssignment = (assign: Required): Assignment => { // send to database, etc. return assign }

const assignVerified: Readonly = { ...assignGraded, verified: true }

recordAssignment({ …assignGraded, verified: true })

// Record const hexColorMap: Record<string, string> = { red: “FF0000”, green: “00FF00”, blue: “0000FF”, }

// Pick and Omit

type AssignResult = Pick<Assignment, “studentId” “grade”>

const score: AssignResult = { studentId: “k123”, grade: 85, }

type AssignPreview = Omit<Assignment, “grade” “verified”>

const preview: AssignPreview = { studentId: “k123”, title: “Final Project”, }

// Exclude and Extract

type adjustedGrade = Exclude<LetterGrades, “U”>

type highGrades = Extract<LetterGrades, “A” “B”>

// Nonnullable

type AllPossibleGrades = ‘Dave’ | ‘John’ | null | undefined type NamesOnly = NonNullable

// ReturnType

const createNewAssign = (title: string, points: number) => { return { title, points } }

type NewAssign = ReturnType

const tsAssign: NewAssign = createNewAssign(“Utility Types”, 100)

// Parameters

type AssignParams = Parameters

const assignArgs: AssignParams = [“Generics”, 100]

const tsAssign2: NewAssign = createNewAssign(…assignArgs)

// Awaited - helps us with the ReturnType of a Promise

interface User { id: number, name: string, username: string, email: string, }

const fetchUsers = async (): Promise<User[]> => {

const data = await fetch(
    'https://jsonplaceholder.typicode.com/users'
).then(res => {
    return res.json()
}).catch(err => {
    if (err instanceof Error) console.log(err.message)
})
return data }

type FetchUsersReturnType = Awaited<ReturnType>


Creative Commons License
This work is licensed under a CC A-S 4.0 International License.