TS 常用工具类型

在 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 {
    // 实现
  }
}

📌 类型定义的最佳实践

  1. 优先使用 interface 定义对象类型,特别是需要扩展的场景
  2. 使用 type 定义联合类型、交叉类型和工具类型
  3. 为所有 API 响应定义完整的类型
  4. 使用 readonly 防止意外修改
  5. 利用泛型提高代码复用性
  6. 避免使用 any,优先使用 unknown

这些是 TypeScript 中最常用和最重要的类型元素,掌握它们可以让你在日常开发中得心应手。

相关推荐
雨季mo浅忆5 分钟前
记录利用Cursor快速实现首页数据大屏
前端·ai编程
像我这样帅的人丶你还5 分钟前
🚀🚀🚀2026年还不会Nginx?
前端·nginx
用户059540174468 分钟前
把对话记忆从内存搬到 Redis,长期记忆准确率从 63% 提升到 98%
前端·css
无心使然8 分钟前
Openlayers图层按需分层渲染到不同Canvas画布
前端·vue.js·gis
西索ovo9 分钟前
从作用域链到闭包,原理一次讲透
javascript
daols8810 分钟前
vxe-table 实现 Excel 风格向下复制填充(Ctrl + D 键)
javascript·vue.js·excel·vxe-table·vxe-ui
木斯佳13 分钟前
前端八股文面经大全:字节跳动-存储部门一面(2026-05-29)·面经深度解析
前端·状态模式
fxshy17 分钟前
Vue 组件中 padding 生效了,但竖线还是贴到底边的问题
javascript·vue.js·ecmascript
ayqy贾杰18 分钟前
有AI了,我当超大头兵还苟得住吗?
前端·后端·架构