TypeScript 类型速查
本文用于快速查阅 TypeScript 常见类型和类型工具。遇到新的变量、参数或接口数据时,可以先判断它属于哪一类,再选择对应写法。
一、类型声明和类型推断
类型声明
ts
let name: string = '孙悟空';
let age: number = 18;
function add(a: number, b: number): number {
return a + b;
}
类型推断
ts
const message = 'hello'; // string
const count = 10; // number
const enabled = true; // boolean
建议:
- 初始值明确、类型简单时,可以使用类型推断。
- 函数参数、公共函数返回值和业务边界建议显式声明。
- 不要为了省代码把所有内容都写成
any。
二、基础类型速查
| 类型 | 示例 | 适用场景 |
|---|---|---|
number |
18 |
普通数字 |
bigint |
100n |
大整数 |
string |
'hello' |
文本 |
boolean |
true |
是或否 |
any |
任意值 | 临时兼容旧代码 |
unknown |
任意值 | 未知但需要安全检查的值 |
void |
无返回值 | 没有返回结果的函数 |
never |
永不正常结束 | 抛异常或无限循环 |
object |
{} |
非原始对象,但结构不明确 |
null |
null |
明确表示空值 |
undefined |
undefined |
明确表示未定义 |
三、any、unknown、void 和 never
any
ts
let value: any = 10;
value = 'hello';
value.notExist();
any 会关闭大量类型检查,只适合临时迁移或无法立即改造的旧代码。
unknown
ts
function print(value: unknown): void {
if (typeof value === 'string') {
console.log(value.toUpperCase());
}
}
未知数据优先使用 unknown,使用前先做类型收窄。
void 和 never
ts
function log(message: string): void {
console.log(message);
}
function fail(message: string): never {
throw new Error(message);
}
| 类型 | 含义 |
|---|---|
void |
函数正常执行结束,但没有有意义的返回值 |
never |
函数不会正常结束 |
四、数组、元组和枚举
数组
ts
const numbers: number[] = [1, 2, 3];
const names: Array<string> = ['Tom', 'Jerry'];
元组
ts
const user: [string, number] = ['孙悟空', 18];
元组用于固定长度和固定顺序的数据。
枚举
ts
enum Status {
Todo = 'todo',
Doing = 'doing',
Done = 'done'
}
const status: Status = Status.Todo;
| 需求 | 类型 |
|---|---|
| 多个同类型元素 | 数组 |
| 固定长度和顺序 | 元组 |
| 一组有名字的常量 | 枚举 |
五、字面量、联合类型和类型别名
字面量类型
ts
let color: 'red' | 'blue';
color = 'red';
联合类型
ts
let id: number | string;
id = 1001;
id = 'user-1001';
类型别名
ts
type OrderStatus = 'pending' | 'success' | 'failed';
type ID = number | string;
使用类型别名可以复用复杂的联合类型和对象结构。
六、类型断言和类型收窄
类型断言
ts
const value: unknown = 'hello';
const length = (value as string).length;
类型断言只告诉编译器如何理解值,不会在运行时转换数据。
类型收窄
ts
function format(value: unknown): string {
if (typeof value === 'string') {
return value.toUpperCase();
}
if (typeof value === 'number') {
return value.toFixed(2);
}
return '';
}
来自用户输入、网络请求或文件的数据,优先使用运行时判断,而不是盲目断言。
七、接口、类和泛型
接口
ts
interface User {
id: number;
name: string;
}
接口适合描述对象结构和类需要遵守的契约。
类
ts
class Person {
constructor(public name: string) {}
}
类适合创建对象模型,并封装数据和行为。
泛型
ts
function identity<T>(value: T): T {
return value;
}
泛型适合在保持类型关系的同时复用函数、类和接口。
八、类型选择决策表
| 问题 | 推荐选择 |
|---|---|
| 这是数字、文本或布尔值吗? | number、string、boolean |
| 类型暂时未知,但需要安全使用吗? | unknown |
| 函数没有返回结果吗? | void |
| 函数永远不会正常结束吗? | never |
| 需要限制为几个固定值吗? | 字面量联合类型 |
| 需要保存同类型列表吗? | 数组 |
| 需要固定长度和顺序吗? | 元组 |
| 需要描述对象结构吗? | 接口或对象类型 |
| 需要创建有属性和行为的对象吗? | 类 |
| 需要复用但类型不固定的逻辑吗? | 泛型 |
九、常用代码模板
函数模板
ts
function fn(parameter: Type): ReturnType {
// ...
}
接口模板
ts
interface Entity {
id: number;
name: string;
}
泛型模板
ts
function fn<T>(value: T): T {
return value;
}
十、本章小结
- 先判断数据的实际含义,再选择类型。
- 不确定的数据优先使用
unknown,避免滥用any。 - 对固定取值使用字面量联合类型。
- 对象结构使用接口,复用类型关系使用泛型。
- 类型断言不是数据转换,外部数据需要运行时校验。