# TypeScript 速查表

Source: https://codewiki.com/zh/cheatsheets/typescript/

## 声明与推断

- `const port: number = 8080` — 为绑定值明确标注类型
- `let result: string | undefined` — 声明可以为 `undefined` 的值
- `const tags = ["ts", "types"]` — 推断可变的字符串数组
- `const role = "admin" as const` — 保留精确的字符串字面量类型
- `const pair = ["id", 42] as const` — 推断只读字面量元组
- `const config = { mode: "prod" } satisfies AppConfig` — 校验结构，同时保留推断出的类型

## 对象与集合

- `type User = { readonly id: string; name?: string }` — 描述对象的只读属性和可选属性
- `interface User { id: string; name?: string }` — 声明可扩展的对象契约
- `type Pair = [label: string, value: number]` — 为元组位置添加便于阅读的标签
- `type Names = readonly string[]` — 禁止通过数组类型写入
- `type Dictionary = { [key: string]: number }` — 描述键名未知而值类型统一的对象
- `type Entity = Identified & Timestamped` — 组合两个结构类型
- `declare const UserIdBrand: unique symbol; type UserId = string & { readonly [UserIdBrand]: true }` — 用唯一符号标记构造名义化字符串类型

## 函数签名

- `function parse(text: string): number { return Number(text); }` — 标注参数类型和返回类型
- `const handler: (event: Event) => void = (event) => event.preventDefault()` — 根据上下文确定回调参数类型
- `type Formatter = (value: number, unit?: string) => string` — 把一个回调参数标记为可选
- `type Sum = (...values: number[]) => number` — 标注剩余参数的类型
- `interface Parse { (value: string): number; (value: number): string }` — 描述重载调用签名
- `function handle(this: HTMLElement, event: Event): void {}` — 声明调用时必需的接收者

## 联合类型与收窄

- `type Status = "idle" | "loading" | "done"` — 把值限制为列出的字面量
- `type Result = { ok: true; value: string } | { ok: false; error: Error }` — 构造带判别字段的结果联合类型
- `typeof value === "string"` — 在运行时收窄原始类型
- `"role" in account` — 根据属性是否存在来收窄类型
- `value instanceof Date` — 根据运行时构造函数收窄类型
- `const isString = (value: unknown): value is string => typeof value === "string"` — 定义可复用的类型谓词
- `function assertString(value: unknown): asserts value is string { if (typeof value !== "string") throw new TypeError("Expected string"); }` — 校验断言正常返回后收窄类型

## 泛型约束

- `function identity(value: T): T { return value; }` — 保留调用方传入的类型
- `function first(items: readonly T[]): T | undefined { return items[0]; }` — 在类型中体现集合可能为空
- `function get<T, K extends keyof T>(value: T, key: K): T[K] { return value[key]; }` — 只接受对象已有的键
- `interface Box { value: T }` — 为可复用的对象契约添加类型参数
- `type ApiResult<T, E = Error> = { data: T } | { error: E }` — 为类型参数提供默认值
- `class Store { constructor(readonly value: T) {} }` — 把类的类型参数限制为对象类型

## 类型查询

- `type Config = typeof config` — 从值声明派生类型
- `type ConfigKey = keyof Config` — 把对象属性键收集为联合类型
- `type Mode = Config["mode"]` — 查询单个属性的类型
- `type Item = (typeof items)[number]` — 提取数组元素类型
- `type ValueOf = T[keyof T]` — 收集对象各属性的值类型
- `type Created = ReturnType<typeof createUser>` — 提取函数返回类型
- `type CreateArgs = Parameters<typeof createUser>` — 把参数提取为元组

## 映射转换

- `type Optional = { [K in keyof T]?: T[K] }` — 把所有属性变为可选
- `type Mutable = { -readonly [K in keyof T]: T[K] }` — 移除属性的只读修饰符
- `type Concrete = { [K in keyof T]-?: T[K] }` — 移除属性的可选修饰符
- `type Flags = { [K in keyof T]: boolean }` — 把所有属性映射为同一种值类型
- ``type Getters = { [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K] }`` — 把属性名重映射为 getter 名称
- `type StringsOnly = { [K in keyof T as T[K] extends string ? K : never]: T[K] }` — 只保留值为字符串的属性

## 条件类型与 infer

- `type MessageOf = T extends { message: unknown } ? T["message"] : never` — 在属性存在时选取其类型
- `type Element = T extends readonly (infer U)[] ? U : never` — 推断只读数组的元素类型
- `type Head = T extends readonly [infer H, ...unknown[]] ? H : never` — 推断元组的第一个元素
- `type Unwrap = T extends PromiseLike<infer U> ? Unwrap : T` — 递归解包类 Promise 值
- `type Distributed = T extends unknown ? T[] : never` — 对联合类型的每个成员分别计算
- `type NonDistributed = [T] extends [unknown] ? T[] : never` — 用方括号包裹检查以阻止分布

## 字面量组合

- `type Direction = "up" | "down"` — 组合有限的字符串字面量联合类型
- ``type Route = `/users/${string}``` — 要求固定的路由前缀
- ``type CssSize = `${number}px``` — 要求数值形式的 CSS 像素值
- ``type EventName = `on${Capitalize}``` — 派生首字母大写的事件名
- ``type EnvKey = `APP_${Uppercase}``` — 派生大写的环境变量名
- ``type Position = `${"top" | "bottom"}-${"left" | "right"}``` — 生成联合类型的所有组合

## 工具类型

- `Partial` — 把所有属性变为可选
- `Required` — 把所有属性变为必需
- `Readonly` — 把所有属性变为只读
- `Pick<User, "id" | "name"` — 保留选中的对象属性
- `Omit<User, "password"` — 移除选中的对象属性
- `Record<Status, Handler>` — 把每个键映射到同一种值类型
- `Exclude<Status, "error"` — 从联合类型中移除成员

## 模块与声明

- `import { value } from "./mod.js"` — 导入运行时绑定
- `import type { User } from "./user.js"` — 导入类型且不产生运行时依赖
- `export { value } from "./mod.js"` — 重新导出运行时绑定
- `export type { User } from "./user.js"` — 重新导出类型且不生成运行时代码
- `import data from "./data.json" with { type: "json" }` — 使用当前的导入属性语法
- `declare module "legacy-lib" { export function load(): unknown; }` — 在声明文件中描述无类型的外部模块
- `export {}; declare global { interface Window { appVersion: string } }` — 从模块中增强全局作用域

## 编译器与项目

- `"strict": true` — 在共享配置中明确启用严格检查
- `"target": "es2025"` — 选择 TypeScript 6 的 ES2025 基线
- `"module": "nodenext"` — 遵循当前的 Node 模块规则
- `"types": ["node"]` — 在默认列表为空时显式引入 Node 环境类型
- `"rootDir": "./src"` — 明确保持预期的输出目录结构
- `npx tsc --noEmit` — 检查已配置的项目且不输出文件
- `npx tsc -b` — 构建项目引用图
