在 TypeScript 中,常用元素类型 可以从两个维度来理解:一是基础数据类型 (Basic Types),二是复合/高级类型(Advanced Types)。下面我将系统地整理这些类型,并附上实际开发中的使用场景。
📋 基础数据类型
1. 原始类型
typescript
// 基本类型
let isDone: boolean = false
let count: number = 42
let name: string = 'TypeScript'
let notDefined: undefined = undefined
let empty: null = null
// 特殊类型
let anything: any = '可以是任何值' // 尽量避免使用
let unknownValue: unknown = 4 // 类型安全的 any
let nothing: void = undefined // 函数无返回值
let neverReturns: never // 永远不会发生的类型
2. 数组和元组
typescript
// 数组 (Array)
let numbers: number[] = [1, 2, 3]
let strings: Array<string> = ['a', 'b', 'c']
let mixed: (string | number)[] = [1, 'two', 3]
// 元组 (Tuple) - 固定长度和类型的数组
let user: [number, string, boolean] = [1, 'Alice', true]
let httpResponse: [number, string] = [200, 'OK']
// 可选元素的元组
let optionalTuple: [string, number?] = ['hello']
optionalTuple = ['hello', 123]
// 剩余元素的元组
let restTuple: [number, ...string[]] = [1, 'a', 'b', 'c']
3. 对象类型
typescript
// 简单对象类型
let point: { x: number; y: number } = { x: 10, y: 20 }
// 可选属性
let config: {
url: string
method?: 'GET' | 'POST'
timeout?: number
} = { url: '/api' }
// 只读属性
let settings: {
readonly id: string
name: string
} = { id: '123', name: 'app' }
// settings.id = '456' // ❌ 错误
🎯 常用复合类型
1. 接口 (Interface)
typescript
// 基础接口
interface User {
id: number
name: string
email: string
age?: number // 可选属性
readonly createdAt: Date // 只读属性
}
// 接口继承
interface Employee extends User {
department: string
salary: number
}
// 接口合并(声明合并)
interface Window {
title: string
}
interface Window {
width: number
}
// Window 现在有 title 和 width 两个属性
2. 类型别名 (Type Alias)
typescript
// 基本类型别名
type UserID = number | string
type Status = 'pending' | 'success' | 'error'
// 对象类型别名
type Point = {
x: number
y: number
}
// 联合类型
type Shape = Circle | Square | Triangle
// 交叉类型
type Draggable = { drag: () => void }
type Resizable = { resize: () => void }
type UIElement = Draggable & Resizable
// 函数类型
type Callback = (data: string) => void
type AsyncFunction<T> = () => Promise<T>
3. 函数类型
typescript
// 函数声明
function add(x: number, y: number): number {
return x + y
}
// 函数表达式
const multiply: (x: number, y: number) => number = (x, y) => x * y
// 函数类型别名
type MathOperation = (a: number, b: number) => number
const divide: MathOperation = (a, b) => a / b
// 可选参数和默认参数
function greet(name: string, greeting: string = 'Hello'): string {
return `${greeting}, ${name}`
}
// 剩余参数
function sum(...numbers: number[]): number {
return numbers.reduce((acc, curr) => acc + curr, 0)
}
// 函数重载
function process(input: string): string[]
function process(input: number): number[]
function process(input: string | number): string[] | number[] {
if (typeof input === 'string') {
return input.split('')
}
return Array.from({ length: input }, (_, i) => i)
}
🚀 高级类型
1. 泛型 (Generics)
typescript
// 泛型函数
function identity<T>(arg: T): T {
return arg
}
const num = identity<number>(42)
const str = identity('hello') // 类型推断
// 泛型接口
interface Box<T> {
value: T
getValue: () => T
}
// 泛型类
class Stack<T> {
private items: T[] = []
push(item: T): void {
this.items.push(item)
}
pop(): T | undefined {
return this.items.pop()
}
}
// 泛型约束
interface Lengthwise {
length: number
}
function logLength<T extends Lengthwise>(arg: T): T {
console.log(arg.length)
return arg
}
2. 联合类型 (Union Types) 和交叉类型 (Intersection Types)
typescript
// 联合类型 - "或"
type ID = number | string
type Result = Success | Failure
// 类型守卫
function processId(id: ID): string {
if (typeof id === 'string') {
return id.toUpperCase()
}
return id.toString()
}
// 可辨识联合(Discriminated Unions)
interface Circle {
kind: 'circle'
radius: number
}
interface Square {
kind: 'square'
sideLength: number
}
type Shape = Circle | Square
function getArea(shape: Shape): number {
switch (shape.kind) {
case 'circle':
return Math.PI * shape.radius ** 2
case 'square':
return shape.sideLength ** 2
}
}
// 交叉类型 - "且"
interface Person {
name: string
age: number
}
interface Employee {
company: string
role: string
}
type Worker = Person & Employee
// Worker 同时拥有 Person 和 Employee 的所有属性
3. 类型守卫和类型断言
typescript
// 类型守卫
function isString(value: unknown): value is string {
return typeof value === 'string'
}
// 使用类型守卫
function process(value: string | number) {
if (isString(value)) {
return value.toUpperCase() // TypeScript 知道这里是 string
}
return value.toFixed(2) // TypeScript 知道这里是 number
}
// 类型断言
const canvas = document.getElementById('canvas') as HTMLCanvasElement
const input = <HTMLInputElement>document.querySelector('input')
// 非空断言
const element = document.querySelector('.exists')!
element.innerHTML = 'Hello'
// 双重断言(谨慎使用)
const expr = '42' as any as number
📦 内置工具类型
1. 常用的 Utility Types
typescript
interface Todo {
title: string
description: string
completed: boolean
createdAt: Date
}
// Partial - 所有属性可选
type PartialTodo = Partial<Todo>
// { title?: string; description?: string; completed?: boolean; createdAt?: Date }
// Required - 所有属性必选
type RequiredTodo = Required<PartialTodo>
// 全部变成必选
// Readonly - 所有属性只读
type ReadonlyTodo = Readonly<Todo>
// 不能修改属性
// Pick - 选取指定属性
type TodoPreview = Pick<Todo, 'title' | 'completed'>
// { title: string; completed: boolean }
// Omit - 排除指定属性
type TodoWithoutDate = Omit<Todo, 'createdAt'>
// { title: string; description: string; completed: boolean }
// Record - 键值对映射
type PageInfo = Record<'home' | 'about' | 'contact', { title: string }>
// {
// home: { title: string }
// about: { title: string }
// contact: { title: string }
// }
// Exclude - 从联合类型中排除
type T = Exclude<'a' | 'b' | 'c', 'a'> // 'b' | 'c'
// Extract - 提取共有类型
type T0 = Extract<'a' | 'b' | 'c', 'a' | 'f'> // 'a'
// NonNullable - 排除 null 和 undefined
type T1 = NonNullable<string | number | null | undefined> // string | number
// ReturnType - 获取函数返回类型
function createUser() {
return { id: 1, name: 'John' }
}
type UserType = ReturnType<typeof createUser> // { id: number; name: string }
// Parameters - 获取函数参数类型
type CreateUserParams = Parameters<typeof createUser> // []
2. 条件类型
typescript
// 基础条件类型
type IsString<T> = T extends string ? true : false
type A = IsString<'hello'> // true
type B = IsString<number> // false
// 分布式条件类型
type ToArray<T> = T extends any ? T[] : never
type StrNumArr = ToArray<string | number> // string[] | number[]
// infer 关键字
type UnpackPromise<T> = T extends Promise<infer U> ? U : T
type PromiseType = UnpackPromise<Promise<string>> // string
// 内置条件类型
type NonFunction<T> = T extends Function ? never : T
🎨 实际应用场景示例
1. API 响应类型
typescript
// API 通用响应结构
interface ApiResponse<T = any> {
code: number
data: T
message: string
timestamp: number
}
// 分页数据结构
interface PaginatedData<T> {
items: T[]
total: number
page: number
pageSize: number
hasMore: boolean
}
// 具体业务类型
interface User {
id: number
name: string
email: string
role: 'admin' | 'user' | 'guest'
}
// 组合使用
type UserListResponse = ApiResponse<PaginatedData<User>>
2. Vue 3 组合式函数类型
typescript
// 异步状态管理
interface AsyncState<T> {
data: Ref<T | null>
loading: Ref<boolean>
error: Ref<Error | null>
execute: () => Promise<void>
}
// 分页状态
interface PaginationState<T> {
list: Ref<T[]>
currentPage: Ref<number>
pageSize: Ref<number>
total: Ref<number>
loading: Ref<boolean>
loadMore: () => Promise<void>
refresh: () => Promise<void>
}
// 表单验证
type ValidationRule<T> = {
validator: (value: T) => boolean
message: string
}
type FormRules<T> = {
[K in keyof T]?: ValidationRule<T[K]>[]
}
3. 事件处理类型
typescript
// DOM 事件
function handleClick(event: MouseEvent): void {
console.log(event.clientX, event.clientY)
}
function handleChange(event: Event): void {
const input = event.target as HTMLInputElement
console.log(input.value)
}
// 自定义事件
interface CustomEvents {
'user-login': { userId: number; timestamp: Date }
'user-logout': { userId: number }
'error': { message: string; code: number }
}
type EventCallback<T> = (data: T) => void
class EventEmitter {
private events: Map<keyof CustomEvents, EventCallback<any>[]> = new Map()
on<K extends keyof CustomEvents>(
event: K,
callback: EventCallback<CustomEvents[K]>
): void {
// 实现
}
emit<K extends keyof CustomEvents>(
event: K,
data: CustomEvents[K]
): void {
// 实现
}
}
📌 类型定义的最佳实践
- 优先使用 interface 定义对象类型,特别是需要扩展的场景
- 使用 type 定义联合类型、交叉类型和工具类型
- 为所有 API 响应定义完整的类型
- 使用 readonly 防止意外修改
- 利用泛型提高代码复用性
- 避免使用 any,优先使用 unknown
这些是 TypeScript 中最常用和最重要的类型元素,掌握它们可以让你在日常开发中得心应手。