主题
TypeScript 基础
一、为什么需要 TypeScript
JavaScript 太"自由",等到运行时才发现传错了类型。TypeScript 在开发阶段就帮你检查类型,还能让 IDE 智能提示。
ts
// 没有 TS:用户传什么都行,写错了不知道
function calcTotal(price, count) { return price * count }
calcTotal('abc', [1, 2]) // 悄悄出错
// 有 TS:编译器直接报错
function calcTotal(price: number, count: number): number {
return price * count
}
calcTotal('abc', 1) // ❌ 参数类型错误,保存时就红了Vue 3 和 React 18 官方都推荐 TypeScript。Vite 工程创建时勾选即可启用。
二、基础类型标注
ts
let id: number = 1
let name: string = '手机'
let inStock: boolean = true
let tags: string[] = ['新品', '热卖'] // 字符串数组
let tuple: [number, string] = [1, '手机'] // 元组
// 字面量联合类型:只有这几个取值
type OrderStatus = 'PENDING' | 'PAID' | 'SHIPPED' | 'CANCELLED'
let status: OrderStatus = 'PENDING'三、接口与类型别名
ts
// 定义"商品"的接口,前端全局通用
export interface Product {
id: number
name: string
price: number
stock: number
image?: string // ? 表示可选
categoryName?: string
}
const p: Product = { id: 1, name: '手机', price: 3999, stock: 10 }与后端对齐
前端 interface 的字段名和类型,必须与后端返回的 JSON 一一对应。联调时字段对不上,就是前后端没对齐——这也是为什么需要接口文档(第 8 部分)。
四、泛型(重点)
泛型让"类型"变成参数,一个函数适配多种类型:
ts
// 后端常见的分页返回结构
interface PageResult<T> {
total: number // 总条数
records: T[] // 当前页数据
current: number // 当前页
size: number // 每页条数
}
const productPage: PageResult<Product> = {
total: 120,
records: [{ id: 1, name: '手机', price: 3999, stock: 10 }],
current: 1,
size: 10,
}前端封装请求时常用泛型:
ts
async function get<T>(url: string): Promise<T> {
const res = await fetch(url)
return res.json()
}
const page = await get<PageResult<Product>>('/api/product/list?page=1')五、联合类型与类型收窄
ts
type Result<T> = { code: number; message: string; data: T | null }
const r: Result<Product> = { code: 200, message: 'ok', data: p }
if (r.data) {
console.log(r.data.name) // 收窄后 TS 知道它是 Product
} else {
console.log('没有数据')
}六、infer / 高级用法(了解即可)
面试偶尔会问,实际开发中偏少:
ts
// 从函数类型里"取"出返回值类型
type ReturnTypeOf<T> = T extends (...args: any[]) => infer R ? R : never
type R = ReturnTypeOf<() => Promise<Product>> // Promise<Product>七、TS 在商城项目中的落地
以"商品列表接口"为例,完整类型定义:
ts
// types/product.ts
export interface Product {
id: number
name: string
description: string
price: number
stock: number
image: string
categoryId: number
categoryName: string
createdAt: string
}
// 请求商品列表的返回
export interface ProductPage {
records: Product[]
total: number
current: number
size: number
}命名约定
- 类型用
interface或type,首字母大写(Product)。 - 文件名小写驼峰(
product.ts)。 - 一个文件里集中定义相关类型,全项目复用。