TypeScript 高级类型
TypeScript 是 JavaScript 的超集,通过类型系统在编译时捕获错误,高级类型系统(泛型、联合类型、映射类型等)能让代码更安全、更易维护,是现代前端和 Node.js 开发的标配。
核心知识点
| 知识点 | 说明 |
|---|
| 语言类型 | JavaScript 的静态类型超集 |
| 最新版本 | TypeScript 5.7+ |
| 核心优势 | 编译时类型检查、IDE 智能提示、重构安全 |
| 运行方式 | 编译为 JavaScript 后运行 |
| 高级特性 | 泛型、联合类型、交叉类型、映射类型、条件类型 |
安装配置
npm install -g typescript # 全局安装 TypeScript
tsc --version # 查看版本
# 初始化 TypeScript 项目
tsc --init # 生成 tsconfig.json
基本使用
1. 基础类型
// 基本类型
let name: string = "TypeScript"; // 字符串
let age: number = 25; // 数字
let isDone: boolean = false; // 布尔
let scores: number[] = [8, 9, 7]; // 数组
let pair: [string, number] = ["TP53", 8.5]; // 元组
// 接口(定义对象结构)
interface Sample {
id: string; // 必需属性
diagnosis: string;
bmi?: number; // 可选属性(?)
readonly created_at: string; // 只读属性
}
const sample: Sample = {
id: "T2D_001",
diagnosis: "T2D",
bmi: 28.5,
created_at: "2025-01-01"
};
2. 联合类型和类型守卫
// 联合类型:值可以是多种类型之一
type DiagnosisResult = string | number | null;
function formatResult(result: DiagnosisResult): string {
if (typeof result === "string") { // 类型守卫
return result.toUpperCase();
} else if (typeof result === "number") {
return result.toFixed(2);
}
return "N/A";
}
// 字面量类型
type Diagnosis = "T2D" | "Healthy" | "Prediabetes"; // 只允许这三个值
let d: Diagnosis = "T2D"; // OK
// let d2: Diagnosis = "Other"; // 编译错误!
3. 泛型
// 泛型函数
function getFirst<T>(arr: T[]): T | undefined { // T 是类型参数
return arr[0];
}
const num = getFirst([1, 2, 3]); // 自动推断为 number
const str = getFirst(["a", "b"]); // 自动推断为 string
// 泛型接口
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
// 使用泛型接口
const response: ApiResponse<Sample[]> = {
data: [{ id: "T2D_001", diagnosis: "T2D", created_at: "2025-01-01" }],
status: 200,
message: "success"
};
// 泛型约束
interface HasId { id: string; }
function findById<T extends HasId>(items: T[], id: string): T | undefined {
return items.find(item => item.id === id); // T 必须有 id 属性
}
高级用法
1. 映射类型和工具类型
// 内置工具类型
type PartialSample = Partial<Sample>; // 所有属性变可选
type RequiredSample = Required<Sample>; // 所有属性变必需
type ReadonlySample = Readonly<Sample>; // 所有属性变只读
type PickedSample = Pick<Sample, "id" | "diagnosis">; // 选取部分属性
type OmittedSample = Omit<Sample, "bmi">; // 排除部分属性
// Record 类型
type GeneExpression = Record<string, number>; // { [key: string]: number }
const expression: GeneExpression = {
"TP53": 8.5,
"BRCA1": 6.2,
"EGFR": 9.1
};
2. 条件类型
// 条件类型
type IsString<T> = T extends string ? "是字符串" : "不是字符串";
type A = IsString<string>; // "是字符串"
type B = IsString<number>; // "不是字符串"
// 实用的条件类型
type NonNullable<T> = T extends null | undefined ? never : T;
type ExtractString<T> = T extends string ? T : never;
3. 类型推断(infer)
// 提取函数返回类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
function analyze(): { gene: string; score: number } {
return { gene: "TP53", score: 0.95 };
}
type AnalysisResult = ReturnType<typeof analyze>;
// { gene: string; score: number }
常见报错与解决
| 报错信息 | 原因 | 解决方法 |
|---|
Type X is not assignable to type Y | 类型不匹配 | 检查类型定义或用类型断言 |
Property does not exist on type | 访问不存在的属性 | 检查接口定义或用可选链 ?. |
Object is possibly undefined | 可能是 undefined | 用 !(断言非空)或 ?.(可选链) |
Generic type requires type arguments | 泛型需要类型参数 | 提供类型参数 <Type> |
速查表
// ===== TypeScript 高级类型速查表 =====
// 联合 & 交叉
type A = string | number; // 联合:A 或 B
type B = TypeA & TypeB; // 交叉:A 且 B
// 工具类型
Partial<T> // 全部可选
Required<T> // 全部必需
Readonly<T> // 全部只读
Pick<T, K> // 选取属性
Omit<T, K> // 排除属性
Record<K, V> // 键值对类型
Exclude<T, U> // 排除类型
Extract<T, U> // 提取类型
NonNullable<T> // 排除 null/undefined
ReturnType<T> // 函数返回类型
Parameters<T> // 函数参数类型
// 泛型
function f<T>(x: T): T { return x; }
interface I<T> { data: T; }
class C<T> { value: T; }
// 类型守卫
typeof x === "string"
x instanceof Class
"prop" in obj
// 类型断言
value as Type
value! // 非空断言