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
```bash
bash
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
undefined
cat > 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 {}
    ) должны иметь префикс
    I
    — e.g.
    IUser
    ,
    IApiResponse
    .
  • Enums (
    enum X {}
    ) должны иметь префикс
    E
    — e.g.
    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+)

satisfies
操作符(TS 5.0+)

Проверяет соответствие типу, сохраняя вывод типов:
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 | undefined
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 | 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);          // Ошибка: у числа нет length
typescript
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()
  };
}

Справочник вспомогательных типов

辅助类型参考

ТипНазначениеПример
Partial<T>
Все свойства опциональны
Partial<User>
Required<T>
Все свойства обязательны
Required<Config>
Pick<T, K>
Выбрать определенные свойства
Pick<User, "id" | "name">
Omit<T, K>
Исключить определенные свойства
Omit<User, "password">
Record<K, V>
Объект с типизированными ключами/значениями
Record<string, number>
ReturnType<F>
Извлечь тип возвращаемого значения функции
ReturnType<typeof fn>
Parameters<F>
Извлечь типы параметров функции
Parameters<typeof fn>
Awaited<T>
Развернуть тип Promise
Awaited<Promise<User>>
类型用途示例
Partial<T>
将所有属性设为可选
Partial<User>
Required<T>
将所有属性设为必填
Required<Config>
Pick<T, K>
选择指定属性`Pick<User, "id"
Omit<T, K>
排除指定属性
Omit<User, "password">
Record<K, V>
创建键值对类型化的对象
Record<string, number>
ReturnType<F>
提取函数返回值类型
ReturnType<typeof fn>
Parameters<F>
提取函数参数类型
Parameters<typeof fn>
Awaited<T>
展开Promise类型
Awaited<Promise<User>>

Условные типы (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)

ИнструментВерсияНазначение
TypeScript5.9+Проверка типов и компиляция
Node.js22 LTSСреда выполнения
Vite7.xИнструмент сборки и dev-сервер
pnpm9.xМенеджер пакетов
ESLint9.xЛинтер с плоской конфигурацией
Vitest3.xФреймворк для тестирования
Prettier3.xФорматирование кода
工具版本用途
TypeScript5.9+类型检查与编译
Node.js22 LTS运行环境
Vite7.x构建工具与开发服务器
pnpm9.x包管理器
ESLint9.x扁平化配置的代码检查器
Vitest3.x测试框架
Prettier3.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,
      },
    },
  }
);

Стратегии миграции

迁移策略

Инкрементальная миграция

增量迁移

  1. Добавьте
    allowJs: true
    и
    checkJs: false
    в
    tsconfig.json
  2. Переименовывайте файлы с
    .js
    на
    .ts
    по одному
  3. Постепенно добавляйте аннотации типов
  4. Включайте более строгие опции инкрементально
  1. tsconfig.json
    中添加
    allowJs: true
    checkJs: false
  2. 将文件逐个从
    .js
    重命名为
    .ts
  3. 逐步添加类型注解
  4. 逐步启用更严格的配置选项

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 获取全面的迁移指南。

Распространенные ошибки

常见错误

MistakeProblemFix
Частое использование
any
Уничтожает типобезопасностьИспользуйте
unknown
и сужайте тип
Игнорирование строгого режимаПропускает ошибки с
null
/
undefined
Включите все строгие опции
Утверждения типа (
as
)
Могут скрыть ошибки типовИспользуйте
satisfies
или защитники типа
Перечисления (enum) для простых объединенийГенерируют код во время выполненияВместо этого используйте литеральные объединения
Отсутствие валидации данных APIНесоответствие типов во время выполненияИспользуйте Zod на границах приложения
错误行为问题修复方案
频繁使用
any
类型
破坏类型安全使用
unknown
并缩小类型范围
忽略严格模式遗漏
null
/
undefined
相关错误
启用所有严格配置选项
滥用类型断言(
as
)
可能隐藏类型错误使用
satisfies
或类型守卫
对简单联合类型使用枚举(enum)生成运行时代码使用字面量联合类型替代
未对API数据进行验证运行时出现类型不匹配在应用边界使用Zod进行验证

Сравнение с другими языками

与其他语言对比

ОсобенностиTypeScriptJavaPython
Система типовСтруктурнаяНоминальнаяПостепенная (утиная типизация)
Null-безопасностьЯвная (
T
|
null
)
@Nullable
аннотации
Опционально через typing
ДженерикиНа уровне типов, стираютсяНа уровне типов, стираютсяВо время выполнения через typing
InterfacesСтруктурное соответствиеДолжны быть реализованыПротокол (3.8+)
EnumsИзбегайте (используйте объединения)ПервоклассныеEnum Класс
特性TypeScriptJavaPython
类型系统结构类型标称类型渐进式(鸭子类型)
Null安全性显式声明(
T
|
null
)
@Nullable
注解
通过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 — 现代化构建工具配置",