TypeScript 5 新功能 — satisfies 运算符与装饰器实战指南
USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。
核心要点 TypeScript 5.0~5.4 的主要新功能: ①
satisfies运算符 — 在保留推断的同时验证类型 ② 标准装饰器 — 符合 TC39 Stage 3 标准,并支持元数据 ③const类型参数 — 字面量类型推断更强 ④ 可扩展多个 tsconfig 档案 ⑤ enum 与 namespace 改进。实战影响最大的是satisfies与新的装饰器。
TypeScript 5 概览
| 项目 | 数值 |
|---|---|
| 主要新功能 | satisfies 运算符、标准装饰器、const 类型参数、可扩展多个 tsconfig、enum 与 namespace 改进 |
| 实战影响最大的功能 | satisfies、新装饰器 |
| 主版本起始日期 | 2023 年 3 月 |
TypeScript 5 是从 2023 年 3 月开始的主版本,从 5.0 到 5.4 之间累积了多次小幅更新。本版本最关键的变化,是引入了 标准装饰器 与 satisfies 运算符。
各版本主要发布时程:
| 版本 | 发布 | 主要功能 |
|---|---|---|
| TypeScript 5.0 | 2023-03 | satisfies、const 类型参数、扩展多个 tsconfig |
| TypeScript 5.1 | 2023-06 | 独立的 getter/setter 类型、JSX 改进 |
| TypeScript 5.2 | 2023-08 | using/await using 关键字、装饰器元数据 |
| TypeScript 5.3 | 2023-11 | Import Attributes、类型缩窄改进 |
| TypeScript 5.4 | 2024-03 | NoInfer 工具类型、闭包中保留类型缩窄 |
1. satisfies 运算符 — 实战完整指南
satisfies 运算符是 TypeScript 5.0 中最具突破性的功能之一。它跳脱了传统类型断言的限制,可以 在保留类型推断的同时验证类型约束。
原本的痛点
// Problem with the old approach
type Color = "red" | "green" | "blue";
type ColorMap = Record<string, string | number[]>;
// as assertion: type-check yes, inference no
const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [0, 0, 255]
} as ColorMap;
// Now palette.red is inferred as string | number[]
// You need an assertion to use .map()
palette.red.map(x => x); // Error: map does not exist on string | number[]改用 satisfies
// satisfies operator
type Color = "red" | "green" | "blue";
type ColorMap = Record<Color, string | number[]>;
const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [0, 0, 255]
} satisfies ColorMap;
// Type-checked AND literal inference preserved
palette.red.map(x => x); // OK: number[] preserved
palette.green.toUpperCase(); // OK: string preserved
const wrong = { purple: "purple" } satisfies ColorMap; // Error: "purple" is not Color实战模式
模式 1: 验证 API 响应对象
interface ApiConfig {
baseUrl: string;
timeout: number;
retries: number;
}
// satisfies for type check + precise literal inference
const config = {
baseUrl: "https://api.example.com",
timeout: 5000,
retries: 3,
} satisfies ApiConfig;
// config.timeout is 5000 (literal), not just number
type TimeoutType = typeof config.timeout; // 5000模式 2: 路由定义
type Route = {
path: string;
component: React.ComponentType;
auth?: boolean;
};
const routes = [
{ path: "/", component: Home },
{ path: "/dashboard", component: Dashboard, auth: true },
] satisfies Route[];
// routes[0].path stays as literal "/" while still validated against Route模式 3: 多语言翻译对象
type TranslationKey = "hello" | "goodbye" | "welcome";
type Translations = Record<TranslationKey, string>;
const en = {
hello: "Hello",
goodbye: "Goodbye",
welcome: "Welcome",
} satisfies Translations;
const fr = {
hello: "Bonjour",
goodbye: "Au revoir",
// missing welcome -> compile error
} satisfies Translations;2. 标准装饰器 — 完整支持 TC39 Stage 3
TypeScript 5.0 支持 TC39 Stage 3 标准装饰器,这与长期使用的实验性装饰器(experimentalDecorators)是分开的两套机制。
主要差异
| 类别 | 实验性装饰器 | 标准装饰器(5.0+) |
|---|---|---|
| 启用方式 | experimentalDecorators: true | 默认启用(无需 tsconfig 设置) |
| 标准符合度 | 自家实现 | TC39 Stage 3 |
| 执行顺序 | 反向 | 正向 |
| 元数据 | emitDecoratorMetadata | 使用 Symbol.metadata |
| 函数支持 | 有限 | 仅 class |
类装饰器
// TypeScript 5 standard decorator
function sealed(target: typeof SealedClass) {
Object.seal(target);
Object.seal(target.prototype);
}
@sealed
class SealedClass {
greet() { return "Hello!"; }
}方法装饰器
function log(target: any, context: ClassMethodDecoratorContext) {
const methodName = String(context.name);
return function (this: any, ...args: any[]) {
console.log(`[${methodName}] called with`, args);
const result = target.call(this, ...args);
console.log(`[${methodName}] returned`, result);
return result;
};
}
class Calculator {
@log
add(a: number, b: number): number {
return a + b;
}
}
const calc = new Calculator();
calc.add(1, 2);
// [add] called with [1, 2]
// [add] returned 3存取器装饰器
function readonly(target: any, context: ClassAccessorDecoratorContext) {
return {
set() {
throw new Error(`${String(context.name)} is read-only.`);
}
};
}
class Config {
@readonly
accessor version = "1.0.0";
}
const cfg = new Config();
console.log(cfg.version); // "1.0.0"
cfg.version = "2.0.0"; // Error装饰器元数据(TypeScript 5.2)
// Using the metadata API
function validate(target: any, context: ClassFieldDecoratorContext) {
context.metadata[context.name] = { required: true };
}
class UserForm {
@validate
name!: string;
@validate
email!: string;
}
// Reading metadata
const metadata = UserForm[Symbol.metadata];
console.log(metadata); // { name: { required: true }, email: { required: true } }3. const 类型参数
TypeScript 5.0 新增的 const 修饰符,可强化泛型函数的类型推断。
// Old behavior
function identity<T>(value: T): T {
return value;
}
const result = identity(["a", "b", "c"]);
// result: string[] (literal info lost)
// const type parameter
function identityConst<const T>(value: T): T {
return value;
}
const result2 = identityConst(["a", "b", "c"]);
// result2: readonly ["a", "b", "c"] (literal preserved)实战范例: 路由建构器
function createRoute<const Path extends string>(path: Path) {
return { path, url: () => `https://app.example.com${path}` };
}
const homeRoute = createRoute("/");
// homeRoute.path: "/" (literal preserved)
const dashRoute = createRoute("/dashboard");
// dashRoute.path: "/dashboard" (literal preserved)4. 扩展多个 tsconfig 档案
从 TypeScript 5.0 起,tsconfig.json 中的 extends 可以使用数组形式。
// tsconfig.json
{
"extends": [
"@tsconfig/strictest/tsconfig.json",
"@tsconfig/node18/tsconfig.json",
"./custom.tsconfig.json"
],
"compilerOptions": {
"outDir": "dist"
}
}过去需要透过链式继承多个档案,现在只要一个数组就能一次处理多重继承。
5. using / await using 关键字(TypeScript 5.2)
这是为资源管理而新增的关键字,概念上类似 Java 的 try-with-resources。
// Object with Symbol.dispose
class FileHandle {
constructor(public name: string) {
console.log(`open ${name}`);
}
[Symbol.dispose]() {
console.log(`close ${this.name}`);
}
}
function readData() {
using handle = new FileHandle("data.txt");
// do work
return handle.name;
}
// When readData() ends, the handle is automatically disposed.await using 则是配合异步资源(Symbol.asyncDispose)使用的版本。
6. 升级前的检查清单
升级到 TypeScript 5 之前,建议确认以下事项:
- 调整
tsconfig.json:确认experimentalDecorators与新装饰器并存的策略 - 复查现有装饰器写法:执行顺序、元数据 API 的差异
- 升级建构工具:Webpack、Vite、SWC、esbuild 等的兼容性
- 升级 ESLint 与
@typescript-eslint,使其能解析新语法 - 检查所用库的类型定义档,排除不兼容的版本
参考资料: 韩国银行经济统计
常见问题 (FAQ)
Q1. TypeScript 5 中最重要的新功能是哪些?
A: 实战影响最大的是 satisfies 运算符、标准装饰器与 const 类型参数。
Q2. 应该在什么场合使用 satisfies 运算符?
A: 当你想验证一个对象符合特定类型,又同时希望保留它的精确推断结果时使用。
Q3. satisfies 和 as 有什么差别?
A: as 属于类型断言,satisfies 属于类型验证,因此在结构错误时更能安全地捕获错误。
Q4. TypeScript 5 的装饰器和旧版有何不同?
A: 标准装饰器遵循 TC39 流程,行为与原本的 experimentalDecorators 不同。
Q5. const 类型参数为何有用?
A: 它能在泛型函数中保留字面量类型推断,让你能写出更精确的类型。
Q6. 升级到 TypeScript 5 之前要检查什么?
A: tsconfig、装饰器写法、建构工具、ESLint,以及所用库的类型兼容性。
🔧 Related Free Tools
相关
USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...
IT用 ChatGPT 赚取副业收入的 6 种方法 —— 2026 年实用且经过验证的变现指南USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...
IT2026年 ChatGPT vs Claude vs Gemini — AI 聊天机器人性能、定价和使用场景对比USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...
IT网站速度优化 2026:如何让 Core Web Vitals 达到 90+USD/JPY分散は、為替急変局面で一方通貨の過大シェアを防ぎ、月次の再バランスと上限規則で感情的な一括投資を抑える実践設計です。...