TypeScript 高级类型
更新: 10/16/2025 字数: 0 字 时长: 0 分钟
高级类型是 TypeScript 类型系统的强大特性,包括类型别名、联合类型、交叉类型、字面量类型等。掌握这些特性能让我们编写更灵活、更安全的代码。
类型别名 (Type Aliases)
类型别名用 type 关键字为类型创建一个新名字。
基本用法
typescript
// 为基础类型创建别名
type Name = string;
type Age = number;
type IsActive = boolean;
let userName: Name = "Alice";
let userAge: Age = 25;
let active: IsActive = true;
// 为对象类型创建别名
type Point = {
x: number;
y: number;
};
let point: Point = { x: 10, y: 20 };函数类型别名
typescript
// 函数类型
type Operation = (a: number, b: number) => number;
const add: Operation = (a, b) => a + b;
const subtract: Operation = (a, b) => a - b;
const multiply: Operation = (a, b) => a * b;
// 带泛型的函数类型
type Predicate<T> = (value: T) => boolean;
type Mapper<T, U> = (value: T) => U;
const isEven: Predicate<number> = (n) => n % 2 === 0;
const toString: Mapper<number, string> = (n) => n.toString();复杂类型别名
typescript
// 嵌套对象类型
type User = {
id: number;
name: string;
address: {
street: string;
city: string;
country: string;
};
contacts: {
email: string;
phone?: string;
};
};
// 数组和元组类型
type StringArray = string[];
type NumberArray = Array<number>;
type Coordinates = [number, number];
type RGB = [number, number, number];
// 函数重载类型
type Overloaded = {
(s: string): string;
(n: number): number;
(b: boolean): boolean;
};联合类型 (Union Types)
联合类型表示一个值可以是几种类型之一,使用 | 分隔每个类型。
基本联合类型
typescript
// 基础类型联合
type StringOrNumber = string | number;
let value: StringOrNumber;
value = "hello"; // 正确
value = 42; // 正确
// value = true; // 错误
// 函数参数使用联合类型
function formatValue(value: string | number): string {
if (typeof value === "string") {
return value.toUpperCase();
}
return value.toFixed(2);
}
formatValue("hello"); // "HELLO"
formatValue(42); // "42.00"字面量联合类型
typescript
// 字符串字面量联合
type Direction = "north" | "south" | "east" | "west";
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
function move(direction: Direction) {
console.log(`Moving ${direction}`);
}
move("north"); // 正确
// move("up"); // 错误
// 数字字面量联合
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
function rollDice(): DiceRoll {
return (Math.floor(Math.random() * 6) + 1) as DiceRoll;
}
// 混合字面量联合
type Status = "success" | "error" | 404 | 500;
type BooleanLike = true | false | 1 | 0 | "yes" | "no";对象联合类型
typescript
// 判别联合(Discriminated Unions)
type Square = {
kind: "square";
size: number;
};
type Rectangle = {
kind: "rectangle";
width: number;
height: number;
};
type Circle = {
kind: "circle";
radius: number;
};
type Shape = Square | Rectangle | Circle;
function getArea(shape: Shape): number {
switch (shape.kind) {
case "square":
return shape.size ** 2;
case "rectangle":
return shape.width * shape.height;
case "circle":
return Math.PI * shape.radius ** 2;
}
}
// 使用
const square: Shape = { kind: "square", size: 10 };
const area = getArea(square); // 100联合类型的类型守护
typescript
type NetworkLoadingState = {
state: "loading";
};
type NetworkFailedState = {
state: "failed";
code: number;
};
type NetworkSuccessState = {
state: "success";
response: {
title: string;
duration: number;
summary: string;
};
};
type NetworkState =
| NetworkLoadingState
| NetworkFailedState
| NetworkSuccessState;
function renderState(state: NetworkState): string {
// 使用类型守护
switch (state.state) {
case "loading":
return "Loading...";
case "failed":
return `Error ${state.code}`;
case "success":
return `Downloaded ${state.response.title}`;
}
}交叉类型 (Intersection Types)
交叉类型将多个类型合并为一个类型,使用 & 连接。
基本交叉类型
typescript
type Person = {
name: string;
age: number;
};
type Employee = {
employeeId: number;
department: string;
};
// 交叉类型包含两个类型的所有属性
type Staff = Person & Employee;
const staff: Staff = {
name: "Alice",
age: 30,
employeeId: 12345,
department: "Engineering"
};Mixin 模式
typescript
// 定义基础类型
type Loggable = {
log(): void;
};
type Serializable = {
serialize(): string;
};
type Timestamped = {
timestamp: Date;
};
// 组合多个类型
type LoggedSerializedTimestamped = Loggable & Serializable & Timestamped;
class DataRecord implements LoggedSerializedTimestamped {
timestamp = new Date();
log() {
console.log("Logging data...");
}
serialize() {
return JSON.stringify(this);
}
}交叉类型与联合类型的结合
typescript
type A = { a: number };
type B = { b: string };
type C = { c: boolean };
// 联合类型的交叉类型
type AB = A & B; // { a: number; b: string }
type BC = B & C; // { b: string; c: boolean }
// 交叉类型的联合类型
type Union = (A & B) | (B & C);
const value1: Union = { a: 1, b: "hello" }; // 正确
const value2: Union = { b: "world", c: true }; // 正确类型冲突
typescript
type A = {
value: string;
};
type B = {
value: number;
};
// 交叉类型产生冲突
type C = A & B;
// C 的 value 类型是 string & number,即 never
const c: C = {
// value 无法赋值,因为不存在既是 string 又是 number 的值
value: "hello" as never
};字面量类型 (Literal Types)
字面量类型是更具体的类型,可以是字符串、数字或布尔值的具体值。
字符串字面量类型
typescript
type Easing = "ease-in" | "ease-out" | "ease-in-out";
class UIElement {
animate(dx: number, dy: number, easing: Easing) {
if (easing === "ease-in") {
// ...
} else if (easing === "ease-out") {
// ...
} else if (easing === "ease-in-out") {
// ...
}
}
}
let element = new UIElement();
element.animate(0, 0, "ease-in"); // 正确
// element.animate(0, 0, "ease-up"); // 错误数字字面量类型
typescript
type DiceValue = 1 | 2 | 3 | 4 | 5 | 6;
type HttpStatus = 200 | 404 | 500;
type Version = 1 | 2 | 3;
function rollDice(): DiceValue {
return (Math.floor(Math.random() * 6) + 1) as DiceValue;
}
function handleResponse(status: HttpStatus) {
switch (status) {
case 200:
console.log("Success");
break;
case 404:
console.log("Not Found");
break;
case 500:
console.log("Server Error");
break;
}
}布尔字面量类型
typescript
type True = true;
type False = false;
// 通常用于类型守护
function isTrue(value: any): value is True {
return value === true;
}
// 限制函数参数
function setFlag(flag: true) {
console.log("Flag is set");
}
setFlag(true); // 正确
// setFlag(false); // 错误模板字面量类型
typescript
// 基本模板字面量
type World = "world";
type Greeting = `hello ${World}`; // "hello world"
// 联合类型的模板字面量
type Color = "red" | "blue" | "green";
type Shade = "light" | "dark";
type ColorShade = `${Shade}-${Color}`;
// "light-red" | "light-blue" | "light-green" | "dark-red" | "dark-blue" | "dark-green"
// 事件名称生成
type PropEventSource<T> = {
on<K extends string & keyof T>(
eventName: `${K}Changed`,
callback: (newValue: T[K]) => void
): void;
};
declare function makeWatchedObject<T>(obj: T): T & PropEventSource<T>;
const person = makeWatchedObject({
firstName: "Alice",
age: 30
});
person.on("firstNameChanged", (newValue) => {
// newValue 的类型是 string
console.log(`Name changed to ${newValue}`);
});
person.on("ageChanged", (newValue) => {
// newValue 的类型是 number
console.log(`Age changed to ${newValue}`);
});内置字符串操作类型
typescript
// Uppercase - 转大写
type Loud = Uppercase<"hello">; // "HELLO"
// Lowercase - 转小写
type Quiet = Lowercase<"HELLO">; // "hello"
// Capitalize - 首字母大写
type Cap = Capitalize<"hello">; // "Hello"
// Uncapitalize - 首字母小写
type Uncap = Uncapitalize<"Hello">; // "hello"
// 实际应用
type Methods = "get" | "post" | "put" | "delete";
type MethodHandlers = {
[M in Methods as `handle${Capitalize<M>}`]: () => void;
};
// {
// handleGet: () => void;
// handlePost: () => void;
// handlePut: () => void;
// handleDelete: () => void;
// }类型守护 (Type Guards)
虽然类型守护会在专门章节详细介绍,这里简单展示其在高级类型中的应用。
typeof 类型守护
typescript
function padLeft(value: string, padding: string | number) {
if (typeof padding === "number") {
return " ".repeat(padding) + value;
}
return padding + value;
}
padLeft("Hello", 4); // " Hello"
padLeft("Hello", ">>> "); // ">>> Hello"instanceof 类型守护
typescript
class Bird {
fly() {
console.log("Flying");
}
}
class Fish {
swim() {
console.log("Swimming");
}
}
function move(animal: Bird | Fish) {
if (animal instanceof Bird) {
animal.fly();
} else {
animal.swim();
}
}in 操作符
typescript
type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {
if ("swim" in animal) {
animal.swim();
} else {
animal.fly();
}
}映射类型 (Mapped Types)
映射类型可以基于旧类型创建新类型。
基本映射类型
typescript
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
type Partial<T> = {
[P in keyof T]?: T[P];
};
type Required<T> = {
[P in keyof T]-?: T[P];
};
// 使用
interface Person {
name: string;
age: number;
}
type ReadonlyPerson = Readonly<Person>;
// { readonly name: string; readonly age: number; }
type PartialPerson = Partial<Person>;
// { name?: string; age?: number; }键重映射
typescript
type Getters<T> = {
[P in keyof T as `get${Capitalize<string & P>}`]: () => T[P];
};
interface Person {
name: string;
age: number;
}
type PersonGetters = Getters<Person>;
// {
// getName: () => string;
// getAge: () => number;
// }条件映射
typescript
type NonNullableProperties<T> = {
[P in keyof T]: NonNullable<T[P]>;
};
type StringProperties<T> = {
[P in keyof T as T[P] extends string ? P : never]: T[P];
};
interface User {
id: number;
name: string;
email: string | null;
age: number;
}
type UserStrings = StringProperties<User>;
// { name: string; email: string | null }条件类型 (Conditional Types)
条件类型根据条件表达式选择类型。
基本条件类型
typescript
type TypeName<T> = T extends string
? "string"
: T extends number
? "number"
: T extends boolean
? "boolean"
: T extends undefined
? "undefined"
: T extends Function
? "function"
: "object";
type T0 = TypeName<string>; // "string"
type T1 = TypeName<42>; // "number"
type T2 = TypeName<true>; // "boolean"
type T3 = TypeName<() => void>; // "function"
type T4 = TypeName<string[]>; // "object"分布式条件类型
typescript
// 联合类型会被分发
type ToArray<T> = T extends any ? T[] : never;
type StrArrOrNumArr = ToArray<string | number>;
// string[] | number[] (分发后)
// 而不是 (string | number)[]
// 阻止分发
type ToArrayNonDist<T> = [T] extends [any] ? T[] : never;
type StrOrNumArr = ToArrayNonDist<string | number>;
// (string | number)[]infer 关键字
typescript
// 提取函数返回类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
type Func = () => string;
type Result = ReturnType<Func>; // string
// 提取数组元素类型
type Flatten<T> = T extends Array<infer U> ? U : T;
type Str = Flatten<string[]>; // string
type Num = Flatten<number>; // number
// 提取 Promise 返回类型
type Unpacked<T> = T extends Promise<infer U> ? U : T;
type PromiseStr = Unpacked<Promise<string>>; // string
type RegularStr = Unpacked<string>; // string递归条件类型
typescript
// 深度 Readonly
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};
interface Person {
name: string;
address: {
city: string;
country: string;
};
}
type ReadonlyPerson = DeepReadonly<Person>;
// {
// readonly name: string;
// readonly address: {
// readonly city: string;
// readonly country: string;
// }
// }工具类型 (Utility Types)
TypeScript 提供了许多内置的工具类型。
Partial & Required
typescript
interface Todo {
title: string;
description: string;
completed: boolean;
}
// Partial - 所有属性可选
type PartialTodo = Partial<Todo>;
// { title?: string; description?: string; completed?: boolean }
// Required - 所有属性必需
type RequiredTodo = Required<PartialTodo>;
// { title: string; description: string; completed: boolean }Pick & Omit
typescript
interface User {
id: number;
name: string;
email: string;
age: number;
address: string;
}
// Pick - 选择部分属性
type UserPreview = Pick<User, "id" | "name" | "email">;
// { id: number; name: string; email: string }
// Omit - 排除部分属性
type UserWithoutAddress = Omit<User, "address">;
// { id: number; name: string; email: string; age: number }Record
typescript
// 创建对象类型
type PageInfo = {
title: string;
url: string;
};
type Pages = "home" | "about" | "contact";
const pages: Record<Pages, PageInfo> = {
home: { title: "Home", url: "/" },
about: { title: "About", url: "/about" },
contact: { title: "Contact", url: "/contact" }
};Exclude & Extract
typescript
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type T1 = Exclude<string | number | (() => void), Function>; // string | number
type T2 = Extract<"a" | "b" | "c", "a" | "f">; // "a"
type T3 = Extract<string | number | (() => void), Function>; // () => voidNonNullable
typescript
type T0 = NonNullable<string | number | undefined>; // string | number
type T1 = NonNullable<string[] | null | undefined>; // string[]ReturnType & Parameters
typescript
function f1(a: number, b: string): boolean {
return true;
}
type T0 = ReturnType<typeof f1>; // boolean
type T1 = Parameters<typeof f1>; // [number, string]
// 实际应用
type AsyncReturnType<T extends (...args: any) => Promise<any>> = T extends (
...args: any
) => Promise<infer R>
? R
: never;
async function getData(): Promise<{ name: string; age: number }> {
return { name: "Alice", age: 30 };
}
type Data = AsyncReturnType<typeof getData>; // { name: string; age: number }实战示例
API 响应类型
typescript
type ApiResponse<T> =
| { status: "loading" }
| { status: "error"; error: string }
| { status: "success"; data: T };
// 使用
interface User {
id: number;
name: string;
}
function handleResponse(response: ApiResponse<User>) {
switch (response.status) {
case "loading":
console.log("Loading...");
break;
case "error":
console.log("Error:", response.error);
break;
case "success":
console.log("User:", response.data.name);
break;
}
}深度可选类型
typescript
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
interface Config {
database: {
host: string;
port: number;
credentials: {
username: string;
password: string;
};
};
cache: {
enabled: boolean;
ttl: number;
};
}
type PartialConfig = DeepPartial<Config>;
// 所有嵌套属性都变为可选类型安全的事件系统
typescript
type EventMap = {
click: { x: number; y: number };
change: { value: string };
submit: { data: Record<string, any> };
};
class EventEmitter<T extends Record<string, any>> {
on<K extends keyof T>(event: K, handler: (data: T[K]) => void) {
// 实现
}
emit<K extends keyof T>(event: K, data: T[K]) {
// 实现
}
}
const emitter = new EventEmitter<EventMap>();
emitter.on("click", (data) => {
// data 的类型是 { x: number; y: number }
console.log(data.x, data.y);
});
emitter.emit("click", { x: 10, y: 20 });总结
TypeScript 的高级类型提供了强大的类型操作能力:
- 类型别名:为类型创建新名字
- 联合类型:值可以是多种类型之一
- 交叉类型:组合多个类型
- 字面量类型:更精确的类型定义
- 映射类型:基于旧类型创建新类型
- 条件类型:根据条件选择类型
- 工具类型:内置的类型转换工具