TypeScript笔记精炼版

TS 基础篇

1. 基本类型

typescript 复制代码
let anyValue: any = 1 // 跳过类型检查,少用
let unknownValue: unknown = 1 // 使用前必须收窄,比 any 安全
let neverValue: never // 永远不会出现的值
function fn(): void {} // 没有返回值

let v1: string | null = null // 联合类型
let v2: 1 | 2 | 3 = 3 // 字面量类型

stringnumberbooleannullundefined 是 JS 已有值类型,TS 主要补充的是类型约束能力。多数初始化变量不用手写类型,能推断就交给 TS。

2. 数组

typescript 复制代码
let arr: number[] = [1, 3, 5]
let arr1: Array<string> = ['a']

3. 元组

固定长度、固定位置类型的数组。

typescript 复制代码
let t1: [number, string, number?] = [1, 'a']
t1[0] = 100

4. 枚举

enum 会生成运行时代码;纯常量集合更常用 as const + 联合类型。

typescript 复制代码
enum MyEnum {
    A,
    B,
    C
}

console.log(MyEnum.A)
console.log(MyEnum[0])

const Status = {
    Success: 'success',
    Error: 'error'
} as const

type Status = (typeof Status)[keyof typeof Status]

5. 函数

typescript 复制代码
function MyFn(a: number = 10, b: string, c?: boolean, ...rest: number[]): string {
    return a + b
}

const f = MyFn(2, 'a', true, 2)

6. 接口

typescript 复制代码
interface Obj {
    name: string
    age: number
}

const obj: Obj = {
    name: 'a',
    age: 22
}

7. 类型别名

typescript 复制代码
type MyUserName = string | number

let a: MyUserName = 12
let b: MyUserName = 'abby'

8. 泛型

typescript 复制代码
function myFn<T, U>(a: T, b: U): [T, U] {
    return [a, b]
}

myFn<string, number>('hello', 123) // 显式指定类型
myFn('hello', 123) // 缺省时 TS 自动推断:T 是 string,U 是 number

TS 进阶篇

1. 函数重载

同名函数根据参数类型不同实现不同的效果。

typescript 复制代码
function hello(name: string): string
function hello(age: number): string
function hello(value: string | number): string {
    if (typeof value === 'string') {
        return '你好,我的名字是' + value
    } else if (typeof value === 'number') {
        return `你好,我的年龄是${value}`
    } else {
        return '非法格式'
    }
}

hello('abc')
hello(18)

2. 接口继承

接口支持单继承和多继承,这里是单继承示例。

typescript 复制代码
interface Parent {
    prop1: string
    prop2: number
}

interface Child extends Parent {
    prop3: string
}

const myObj: Child = {
    prop1: '',
    prop2: 1,
    prop3: ''
}

3. 类的修饰符

常见修饰符:public 公有、protected 受保护、private 私有、static 静态属性、readonly 只读不可改。

typescript 复制代码
class Article {
    public title1: string
    content1: string
    dd?: string
    bb = 100

    private tempData?: string
    protected innerData?: string

    // 注意顺序
    private static readonly author: string = 'abbylolo'

    constructor(title: string, protected content: string) {
        this.title1 = title
        this.content1 = content
        // Article.author = 'abby'
    }
}

const article = new Article('标题', '内容')
// article.tempData // private 私有属性不可访问,只能在 Article 类中访问
// article.innerData // protected 只能在 Article 及其子类中访问

class SubArticle extends Article {
    constructor(title: string, content: string) {
        super(title, content)

        this.innerData = 'a'
        // tempData = '1' // private 私有属性不可访问,只能在 Article 类中访问
    }
}

4. 存取器

类似 getter / setter

typescript 复制代码
class User {
    private _password: string = ''

    get password(): string {
        return '****'
    }

    set password(newPass: string) {
        this._password = newPass
    }
}

const u = new User()
console.log(u.password)

5. 抽象类

继承抽象类时必须实现所有抽象属性和抽象方法;抽象类中可以不包含抽象方法。

typescript 复制代码
abstract class Animal {
    abstract name: string
    abstract makeSound(): void

    move(): void {
        console.log('移动')
    }
}

class Cat extends Animal {
    name: string = '小猫'

    makeSound(): void {
    }
}

6. 类实现接口

类可以实现多个接口。

typescript 复制代码
interface Animal2 {
    name: string
    get sound(): string
    makeSound(): void
}

interface B {
    age: number
}

class Dog2 implements Animal2, B {
    name: string = '小狗'
    age: number = 1

    get sound() {
        return ''
    }

    makeSound(): void {
    }
}

7. 泛型类

typescript 复制代码
class MyClass<T> {
    constructor(public value: T) {}

    do(input: T): T {
        console.log('处理数据', this.value)
        return input
    }
}

const myStr = new MyClass<string>('Hello')
myStr.do('abd1')

const myNum = new MyClass<number>(123)
myNum.do(123)

8. 类型收窄

联合类型使用前先收窄。

typescript 复制代码
function printId(id: string | number) {
    if (typeof id === 'string') {
        console.log(id.toUpperCase())
    } else {
        console.log(id.toFixed(2))
    }
}

9. as const 与 satisfies

as const 保留字面量类型;satisfies 校验结构,但不丢失原始推断。

typescript 复制代码
type Route = {
    path: string
    title: string
}

const routes = [
    { path: '/', title: '首页' },
    { path: '/user', title: '用户' }
] as const satisfies readonly Route[]

10. 常用工具类型

工具类型是 TS 内置的类型快捷操作,用来复用和改造已有类型。

typescript 复制代码
type UserInfo = {
    id: number
    name: string
    age: number
}

type UserPartial = Partial<UserInfo> // 所有属性变可选
type UserRequired = Required<UserInfo> // 所有属性变必填
type UserBase = Pick<UserInfo, 'id' | 'name'> // 只保留指定属性
type UserWithoutAge = Omit<UserInfo, 'age'> // 移除指定属性
type UserMap = Record<string, UserInfo> // 定义对象 key/value 类型
type UserReadonly = Readonly<UserInfo> // 所有属性变只读

参考资料