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 // 字面量类型
string、number、boolean、null、undefined 是 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> // 所有属性变只读