typescript
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseОсвоение современного TypeScript
掌握现代TypeScript
Создавайте enterprise-приложения с типобезопасностью на TypeScript 5.9+.
Совместимость: TypeScript 5.9+, Node.js 22 LTS, Vite 7, NestJS 11
使用TypeScript 5.9+创建具备类型安全的企业级应用。
兼容性: TypeScript 5.9+、Node.js 22 LTS、Vite 7、NestJS 11
Быстрый старт
快速入门
bash
```bashbash
undefinedИнициализация TypeScript проекта с ESM
初始化ESM格式的TypeScript项目
pnpm create vite@latest my-app --template vanilla-ts
cd my-app && pnpm install
pnpm create vite@latest my-app --template vanilla-ts
cd my-app && pnpm install
Настройка строгого TypeScript
配置严格模式TypeScript
cat > tsconfig.json << 'EOF'
{
"compilerOptions": {
"target": "ES2024",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
EOF
undefinedcat > tsconfig.json << 'EOF'
{
"compilerOptions": {
"target": "ES2024",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
EOF
undefinedКогда использовать этот навык
适用场景
Используйте когда:
- Создаете типобезопасные приложения на NestJS или Node.js
- Мигрируете кодовую базу с JavaScript на TypeScript
- Внедряете продвинутые паттерны типизации (дженерики, маппинг типов, условные типы)
- Настраиваете современные инструменты TypeScript (Vite, pnpm, ESLint)
- Проектируете типобезопасные контракты API с валидацией Zod
- Сравниваете подходы TypeScript с Java или Python
适用于以下场景:
- 使用NestJS或Node.js创建类型安全应用
- 将代码库从JavaScript迁移至TypeScript
- 实施高级类型模式(泛型、类型映射、条件类型)
- 配置TypeScript现代化工具(Vite、pnpm、ESLint)
- 设计带Zod验证的类型安全API契约
- 对比TypeScript与Java或Python的开发方式
Чек-лист настройки проекта
项目配置检查清单
Перед началом любого TypeScript проекта:
- [ ] Используйте pnpm для управления пакетами (быстрее, экономит место)
- [ ] Настройте ESM как основной модуль ("type": "module" в package.json)
- [ ] Включите строгий режим в tsconfig.json
- [ ] Настройте ESLint с @typescript-eslint
- [ ] Добавьте Prettier для единообразного форматирования
- [ ] Настройте Vitest для тестирования启动任何TypeScript项目前,请完成以下配置:
- [ ] 使用pnpm管理包(更快、节省空间)
- [ ] 将ESM设为主要模块(在package.json中设置"type": "module")
- [ ] 在tsconfig.json中启用严格模式
- [ ] 配置带@typescript-eslint的ESLint
- [ ] 添加Prettier以统一代码格式
- [ ] 配置Vitest用于测试Соглашения об именовании
命名规范
- Псевдонимы типов () должны иметь префикс
type X = ...— например,T,TStatus,TResult.TUnwrapPromise - Interfaces () должны иметь префикс
interface X {}— e.g.I,IUser.IApiResponse - Enums () должны иметь префикс
enum X {}— e.g.E,E,EPlanet.EFilms - Применяется к каждому объявлению в этом навыке и в генерируемом коде.
- 类型别名 () 需添加前缀
type X = ...— 例如T、TStatus、TResult。TUnwrapPromise - 接口 () 需添加前缀
interface X {}— 例如I、IUser。IApiResponse - 枚举 () 需添加前缀
enum X {}— 例如E、EPlanet。EFilms - 本技能及生成代码中的所有声明均遵循此规范。
Краткий справочник по системе типов
类型系统速查
Примитивные типы
原始类型
typescript
const name: string = "Алиса";
const age: number = 30;
const active: boolean = true;
const id: bigint = 9007199254740991n;
const key: symbol = Symbol("уникальный");typescript
const name: string = "爱丽丝";
const age: number = 30;
const active: boolean = true;
const id: bigint = 9007199254740991n;
const key: symbol = Symbol("唯一标识");Union and Intersection Types
联合类型与交叉类型
typescript
// Union: значение может быть одного из нескольких типов
type TStatus = "pending" | "approved" | "rejected";
// Intersection: значение должно удовлетворять всем типам
type TEmployee = IPerson & { employeeId: string };
// Размеченное объединение для типобезопасной обработки
type TResult<T> =
| { success: true; data: T }
| { success: false; error: string };
function handleResult<T>(result: TResult<T>): T | null {
if (result.success) {
return result.data; // Здесь TypeScript знает, что data существует
}
console.error(result.error);
return null;
}typescript
// 联合类型:值可以是多个类型中的一种
type TStatus = "pending" | "approved" | "rejected";
// 交叉类型:值需满足所有类型的要求
type TEmployee = IPerson & { employeeId: string };
// 可区分联合类型,用于类型安全处理
type TResult<T> =
| { success: true; data: T }
| { success: false; error: string };
function handleResult<T>(result: TResult<T>): T | null {
if (result.success) {
return result.data; // 此处TypeScript明确知道data存在
}
console.error(result.error);
return null;
}Type Guards
类型守卫
typescript
// Защитник типа typeof
function process(value: string | number): string {
if (typeof value === "string") {
return value.toUpperCase();
}
return value.toFixed(2);
}
// Пользовательский защитник типа
interface IUser { type: "user"; name: string }
interface IAdmin { type: "admin"; permissions: string[] }
function isAdmin(person: IUser | IAdmin): person is IAdmin {
return person.type === "admin";
}typescript
// typeof类型守卫
function process(value: string | number): string {
if (typeof value === "string") {
return value.toUpperCase();
}
return value.toFixed(2);
}
// 自定义类型守卫
interface IUser { type: "user"; name: string }
interface IAdmin { type: "admin"; permissions: string[] }
function isAdmin(person: IUser | IAdmin): person is IAdmin {
return person.type === "admin";
}Оператор satisfies
(TS 5.0+)
satisfiessatisfies
操作符(TS 5.0+)
satisfiesПроверяет соответствие типу, сохраняя вывод типов:
typescript
// Проблема: утверждение типа теряет конкретную информацию о типе
const colors1 = {
red: "#ff0000",
green: "#00ff00"
} as Record<string, string>;
colors1.red.toUpperCase(); // OK, но red может быть undefined
// Решение: satisfies сохраняет литеральные типы
const colors2 = {
red: "#ff0000",
green: "#00ff00"
} satisfies Record<string, string>;
colors2.red.toUpperCase(); // OK, и TypeScript знает, что red существует检查值是否符合类型,同时保留类型推断信息:
typescript
// 问题:类型断言会丢失具体类型信息
const colors1 = {
red: "#ff0000",
green: "#00ff00"
} as Record<string, string>;
colors1.red.toUpperCase(); // 语法正确,但red可能为undefined
// 解决方案:satisfies保留字面量类型
const colors2 = {
red: "#ff0000",
green: "#00ff00"
} satisfies Record<string, string>;
colors2.red.toUpperCase(); // 语法正确,且TypeScript明确知道red存在Паттерны дженериков
泛型模式
Базовая дженерик-функция
基础泛型函数
typescript
function first<T>(items: T[]): T | undefined {
return items[0];
}
const num = first([1, 2, 3]); // number | undefined
const str = first(["a", "b"]); // string | undefinedtypescript
function first<T>(items: T[]): T | undefined {
return items[0];
}
const num = first([1, 2, 3]); // number | undefined
const str = first(["a", "b"]); // string | undefinedОграниченные дженерики
受限泛型
typescript
interface IHasLength {
length: number;
}
function logLength<T extends IHasLength>(item: T): T {
console.log(item.length);
return item;
}
logLength("hello"); // OK: у строки есть length
logLength([1, 2, 3]); // OK: у массива есть length
logLength(42); // Ошибка: у числа нет lengthtypescript
interface IHasLength {
length: number;
}
function logLength<T extends IHasLength>(item: T): T {
console.log(item.length);
return item;
}
logLength("hello"); // 合法:字符串包含length属性
logLength([1, 2, 3]); // 合法:数组包含length属性
logLength(42); // 错误:数字无length属性Дженерик-обертка для API ответов
API响应泛型包装
typescript
interface IApiResponse<T> {
data: T;
status: number;
timestamp: Date;
}
async function fetchUser(id: string): Promise<IApiResponse<IUser>> {
const response = await fetch(`/api/users/${id}`);
const data = await response.json();
return {
data,
status: response.status,
timestamp: new Date()
};
}typescript
interface IApiResponse<T> {
data: T;
status: number;
timestamp: Date;
}
async function fetchUser(id: string): Promise<IApiResponse<IUser>> {
const response = await fetch(`/api/users/${id}`);
const data = await response.json();
return {
data,
status: response.status,
timestamp: new Date()
};
}Справочник вспомогательных типов
辅助类型参考
| Тип | Назначение | Пример |
|---|---|---|
| Все свойства опциональны | |
| Все свойства обязательны | |
| Выбрать определенные свойства | |
| Исключить определенные свойства | |
| Объект с типизированными ключами/значениями | |
| Извлечь тип возвращаемого значения функции | |
| Извлечь типы параметров функции | |
| Развернуть тип Promise | |
| 类型 | 用途 | 示例 |
|---|---|---|
| 将所有属性设为可选 | |
| 将所有属性设为必填 | |
| 选择指定属性 | `Pick<User, "id" |
| 排除指定属性 | |
| 创建键值对类型化的对象 | |
| 提取函数返回值类型 | |
| 提取函数参数类型 | |
| 展开Promise类型 | |
Условные типы (Conditional Types)
条件类型
typescript
// Базовый условный тип
type TIsString<T> = T extends string ? true : false;
// Извлечение типа элемента массива
type TArrayElement<T> = T extends (infer E)[] ? E : never;
type TNumbers = TArrayElement<number[]>; // number
type TStrings = TArrayElement<string[]>; // string
// Практический пример: извлечение типа результата Promise
type TUnwrapPromise<T> = T extends Promise<infer R> ? R : T;typescript
// 基础条件类型
type TIsString<T> = T extends string ? true : false;
// 提取数组元素类型
type TArrayElement<T> = T extends (infer E)[] ? E : never;
type TNumbers = TArrayElement<number[]>; // number
type TStrings = TArrayElement<string[]>; // string
// 实用示例:提取Promise的结果类型
type TUnwrapPromise<T> = T extends Promise<infer R> ? R : T;Маппинг типов
类型映射
typescript
// Сделать все свойства доступными только для чтения
type TImmutable<T> = {
readonly [K in keyof T]: T[K];
};
// Сделать все свойства nullable
type TNullable<T> = {
[K in keyof T]: T[K] | null;
};
// Создать функции-геттеры для каждого свойства
type TGetters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
interface IPerson { name: string; age: number }
type TPersonGetters = TGetters<IPerson>;
// { getName: () => string; getAge: () => number }typescript
// 将所有属性设为只读
type TImmutable<T> = {
readonly [K in keyof T]: T[K];
};
// 将所有属性设为可空
type TNullable<T> = {
[K in keyof T]: T[K] | null;
};
// 为每个属性创建getter函数
type TGetters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
interface IPerson { name: string; age: number }
type TPersonGetters = TGetters<IPerson>;
// { getName: () => string; getAge: () => number }Интеграция с фреймворками
框架集成
NestJS с TypeScript
TypeScript与NestJS
typescript
// Типобезопасный DTO с class-validator
import { IsString, IsEmail, MinLength } from 'class-validator';
class CreateUserDto {
@IsString()
@MinLength(2)
name: string;
@IsEmail()
email: string;
}
// Или с Zod (современный подход)
import { z } from 'zod';
const CreateUserSchema = z.object({
name: z.string().min(2),
email: z.string().email()
});
type TCreateUserDto = z.infer<typeof CreateUserSchema>;Смотрите nestjs-integration.md для детальных паттернов.
typescript
// 基于class-validator的类型安全DTO
import { IsString, IsEmail, MinLength } from 'class-validator';
class CreateUserDto {
@IsString()
@MinLength(2)
name: string;
@IsEmail()
email: string;
}
// 或使用Zod(现代化方案)
import { z } from 'zod';
const CreateUserSchema = z.object({
name: z.string().min(2),
email: z.string().email()
});
type TCreateUserDto = z.infer<typeof CreateUserSchema>;查看 nestjs-integration.md 获取详细模式。
Валидация с Zod
Zod验证
typescript
import { z } from 'zod';
// Определение схемы
const UserSchema = z.object({
id: z.string().uuid(),
name: z.string().min(1).max(100),
email: z.string().email(),
role: z.enum(["user", "admin", "moderator"]),
createdAt: z.coerce.date()
});
// Вывод типа TypeScript из схемы
type TUser = z.infer<typeof UserSchema>;
// Валидация во время выполнения
function parseUser(data: unknown): TUser {
return UserSchema.parse(data); // Бросает ZodError, если невалидно
}
// Безопасный парсинг (возвращает объект результата)
const result = UserSchema.safeParse(data);
if (result.success) {
console.log(result.data); // Типизирован как User
} else {
console.error(result.error.issues);
}typescript
import { z } from 'zod';
// 定义Schema
const UserSchema = z.object({
id: z.string().uuid(),
name: z.string().min(1).max(100),
email: z.string().email(),
role: z.enum(["user", "admin", "moderator"]),
createdAt: z.coerce.date()
});
// 从Schema推断TypeScript类型
type TUser = z.infer<typeof UserSchema>;
// 运行时验证
function parseUser(data: unknown): TUser {
return UserSchema.parse(data); // 验证失败时抛出ZodError
}
// 安全解析(返回结果对象)
const result = UserSchema.safeParse(data);
if (result.success) {
console.log(result.data); // 类型为User
} else {
console.error(result.error.issues);
}Modern Toolchain (2025)
现代化工具链(2025)
| Инструмент | Версия | Назначение |
|---|---|---|
| TypeScript | 5.9+ | Проверка типов и компиляция |
| Node.js | 22 LTS | Среда выполнения |
| Vite | 7.x | Инструмент сборки и dev-сервер |
| pnpm | 9.x | Менеджер пакетов |
| ESLint | 9.x | Линтер с плоской конфигурацией |
| Vitest | 3.x | Фреймворк для тестирования |
| Prettier | 3.x | Форматирование кода |
| 工具 | 版本 | 用途 |
|---|---|---|
| TypeScript | 5.9+ | 类型检查与编译 |
| Node.js | 22 LTS | 运行环境 |
| Vite | 7.x | 构建工具与开发服务器 |
| pnpm | 9.x | 包管理器 |
| ESLint | 9.x | 扁平化配置的代码检查器 |
| Vitest | 3.x | 测试框架 |
| Prettier | 3.x | 代码格式化工具 |
Плоская конфигурация ESLint (ESLint 9+)
ESLint扁平化配置(ESLint 9+)
javascript
// eslint.config.js
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.strictTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
}
);javascript
// eslint.config.js
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.strictTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
}
);Стратегии миграции
迁移策略
Инкрементальная миграция
增量迁移
- Добавьте и
allowJs: trueвcheckJs: falsetsconfig.json - Переименовывайте файлы с на
.jsпо одному.ts - Постепенно добавляйте аннотации типов
- Включайте более строгие опции инкрементально
- 在中添加
tsconfig.json和allowJs: truecheckJs: false - 将文件逐个从重命名为
.js.ts - 逐步添加类型注解
- 逐步启用更严格的配置选项
JSDoc для постепенной типизации
基于JSDoc的渐进式类型化
javascript
// Перед полной миграцией используйте JSDoc
/**
* @param {string} name
* @param {number} age
* @returns {User}
*/
function createUser(name, age) {
return { name, age };
}Смотрите enterprise-patterns.md для всесторонних руководств по миграции.
javascript
// 完成全量迁移前使用JSDoc
/**
* @param {string} name
* @param {number} age
* @returns {User}
*/
function createUser(name, age) {
return { name, age };
}查看 enterprise-patterns.md 获取全面的迁移指南。
Распространенные ошибки
常见错误
| Mistake | Problem | Fix |
|---|---|---|
Частое использование | Уничтожает типобезопасность | Используйте |
| Игнорирование строгого режима | Пропускает ошибки с | Включите все строгие опции |
Утверждения типа ( | Могут скрыть ошибки типов | Используйте |
| Перечисления (enum) для простых объединений | Генерируют код во время выполнения | Вместо этого используйте литеральные объединения |
| Отсутствие валидации данных API | Несоответствие типов во время выполнения | Используйте Zod на границах приложения |
| 错误行为 | 问题 | 修复方案 |
|---|---|---|
频繁使用 | 破坏类型安全 | 使用 |
| 忽略严格模式 | 遗漏 | 启用所有严格配置选项 |
滥用类型断言( | 可能隐藏类型错误 | 使用 |
| 对简单联合类型使用枚举(enum) | 生成运行时代码 | 使用字面量联合类型替代 |
| 未对API数据进行验证 | 运行时出现类型不匹配 | 在应用边界使用Zod进行验证 |
Сравнение с другими языками
与其他语言对比
| Особенности | TypeScript | Java | Python |
|---|---|---|---|
| Система типов | Структурная | Номинальная | Постепенная (утиная типизация) |
| Null-безопасность | Явная ( | | Опционально через typing |
| Дженерики | На уровне типов, стираются | На уровне типов, стираются | Во время выполнения через typing |
| Interfaces | Структурное соответствие | Должны быть реализованы | Протокол (3.8+) |
| Enums | Избегайте (используйте объединения) | Первоклассные | Enum Класс |
| 特性 | TypeScript | Java | Python |
|---|---|---|---|
| 类型系统 | 结构类型 | 标称类型 | 渐进式(鸭子类型) |
| Null安全性 | 显式声明( | | 通过typing可选支持 |
| 泛型 | 类型层面实现,会被擦除 | 类型层面实现,会被擦除 | 通过typing在运行时实现 |
| 接口 | 结构匹配即可 | 必须显式实现 | 协议(3.8+) |
| 枚举 | 建议避免(使用联合类型替代) | 一等公民 | 枚举类 |
Reference Files
参考文档
- type-system.md — Полное руководство по системе типов
- generics.md — Продвинутые паттерны дженериков
- enterprise-patterns.md — Обработка ошибок, валидация, архитектура
- nestjs-integration.md — Разработка API на NestJS
- toolchain.md — Настройка современных инструментов сборки
- type-system.md — 完整类型系统指南
- generics.md — 高级泛型模式
- enterprise-patterns.md — 错误处理、验证、架构
- nestjs-integration.md — NestJS API开发
- toolchain.md — 现代化构建工具配置",