TypeScript 类型系统完全指南
目录
基本类型
number
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
let big: bigint = 100n; // ES2020
string
let color: string = "blue";
let fullName: string = `Bob Bobbington`;
let sentence: string = `Hello, my name is ${fullName}`;
boolean
let isDone: boolean = false;
let isActive: boolean = true;
null 和 undefined
let u: undefined = undefined;
let n: null = null;
symbol
let sym1: symbol = Symbol();
let sym2: symbol = Symbol("key");
对象类型
object
// 普通对象
let obj: object = { prop: 0 };
// 具体的对象类型
interface Point {
x: number;
y: number;
}
let point: Point = { x: 10, y: 20 };
// 可选属性
interface Config {
color?: string;
width?: number;
}
// 只读属性
interface ReadOnlyPoint {
readonly x: number;
readonly y: number;
}
class
class Animal {
private name: string;
protected age: number;
public type: string;
constructor(name: string, age: number, type: string) {
this.name = name;
this.age = age;
this.type = type;
}
}
interface
interface Vehicle {
brand: string;
model: string;
year: number;
start(): void;
stop(): void;
}
class Car implements Vehicle {
constructor(
public brand: string,
public model: string,
public year: number
) {}
start() { console.log('Starting...'); }
stop() { console.log('Stopping...'); }
}
数组和元组
数组
// 类型+方括号
let list1: number[] = [1, 2, 3];
// 泛型数组
let list2: Array<number> = [1, 2, 3];
// 多类型数组
let list3: (number | string)[] = [1, "hello", 2];
// 只读数组
let readOnlyList: ReadonlyArray<number> = [1, 2, 3];
元组
// 固定长度和类型的数组
let tuple: [string, number] = ["hello", 10];
// 可选元素的元组
let optionalTuple: [string, number?] = ["hello"];
// 剩余元素��元组
let restTuple: [number, ...string[]] = [1, "hello", "world"];
特殊类型
any
let notSure: any = 4;
notSure = "maybe a string";
notSure = false;
unknown
let value: unknown = 4;
if (typeof value === "string") {
console.log(value.toUpperCase());
}
void
function warnUser(): void {
console.log("This is a warning message");
}
never
// 永远不会返回的函数
function error(message: string): never {
throw new Error(message);
}
// 永远不会有返回值的循环
function infiniteLoop(): never {
while (true) {}
}
类型断言和类型守卫
类型断言
// 尖括号语法
let someValue: unknown = "this is a string";
let strLength: number = (<string>someValue).length;
// as 语法
let otherValue: unknown = "this is a string";
let otherLength: number = (otherValue as string).length;
类型守卫
// typeof 类型守卫
function padLeft(value: string, padding: string | number) {
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value;
}
if (typeof padding === "string") {
return padding + value;
}
throw new Error(`Expected string or number, got '${padding}'.`);
}
// instanceof 类型守卫
class Bird {
fly() { console.log("flying..."); }
}
class Fish {
swim() { console.log("swimming..."); }
}
function move(pet: Bird | Fish) {
if (pet instanceof Bird) {
pet.fly();
} else {
pet.swim();
}
}
高级类型
联合类型
let unionType: string | number;
unionType = "hello";
unionType = 42;
交叉类型
interface BusinessPartner {
name: string;
credit: number;
}
interface Identity {
id: number;
email: string;
}
type Employee = BusinessPartner & Identity;
字面量类型
// 字符串字面量
type Easing = "ease-in" | "ease-out" | "ease-in-out";
// 数字字面量
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
索引类型
interface StringArray {
[index: number]: string;
}
let myArray: StringArray = ["Bob", "Fred"];
映射类型
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
type Partial<T> = {
[P in keyof T]?: T[P];
};
实用工具类型
Partial
interface Todo {
title: string;
description: string;
}
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
return { ...todo, ...fieldsToUpdate };
}
Readonly
interface Config {
host: string;
port: number;
}
const config: Readonly<Config> = {
host: "localhost",
port: 3000
};
Record
interface PageInfo {
title: string;
}
type Page = "home" | "about" | "contact";
const nav: Record<Page, PageInfo> = {
home: { title: "Home" },
about: { title: "About" },
contact: { title: "Contact" }
};
Pick
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, "title" | "completed">;
Omit
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoInfo = Omit<Todo, "completed">;
最佳实践
- 尽可能使用具体的类型而不是 any
- 利用类型推断减少冗余的类型注解
- 使用接口定义对象结构
- 使用类型守卫进行类型收窄
- 合理使用工具类型简化代码
总结
TypeScript 的类型系统非常强大,包括:
- 基本类型:number, string, boolean 等
- 对象类型:interface, class 等
- 数组和元组类型
- 特殊类型:any, unknown, void, never
- 高级类型:联合类型、交叉类型等
- 工具类型:Partial, Readonly, Record 等
合理使用这些类型可以:
- 提高代码的可维护性
- 减少运行时错误
- 提供更好的开发体验
- 增强代码的可读性