TypeScript速查手册
TS类型/泛型/工具类型/tsconfig速查
🔷 基础类型
冒号后标注类型;TS 有自动推断,能推断时无需手写。
let str: string = 'hello';
let num: number = 42;
let bool: boolean = true;
let u: undefined = undefined;
let n: null = null;
let big: bigint = 100n;
let sym: symbol = Symbol('k');
let inferred = 'hi'; // 推断为 string
T[] 与 Array<T> 等价;元组长度、每位置类型固定。
let nums: number[] = [1, 2, 3];
let strs: Array<string> = ['a', 'b'];
let matrix: number[][] = [[1], [2, 3]];
let pair: [string, number] = ['Tom', 18];
let triple: [string, number?] = ['Amy'];
let readonlyArr: ReadonlyArray<number> = [1, 2];
尽量别用 any;unknown 是类型安全的 any,用前必须收窄;never 表示永不出现。
let a: any = 1;
a.anything(); // 不报错(放弃类型检查)
let u: unknown = 'x';
if (typeof u === 'string') u.toUpperCase(); // 收窄后才能用
function log(msg: string): void {
console.log(msg);
}
function fail(msg: string): never {
throw new Error(msg);
}
字面量联合可模拟固定取值集合,常比 enum 更轻。
type Dir = 'up' | 'down' | 'left' | 'right';
let d: Dir = 'up';
type Status = 200 | 404 | 500;
enum Color {
Red = 'red',
Green = 'green',
Blue = 'blue'
}
let c: Color = Color.Red;
// 常量枚举/对象 as const 也能得到字面量联合
const MAP = {a: 1, b: 2} as const;
type Key = keyof typeof MAP; // 'a' | 'b'
参数与返回值都可标注;可选参数必须放后面。
function add(a: number, b: number): number {
return a + b;
}
const fn: (x: number, y?: number) => number = (x, y = 0) => x + y;
function rest(...args: number[]): number {
return args.reduce((a, b) => a + b, 0);
}
// 回调函数
function onTick(cb: (ts: number) => void) {
cb(Date.now());
}
🧩 接口与类型别名
描述对象有哪些字段、什么类型,多余/缺少字段都会报错。
interface User {
id: number;
name: string;
email?: string; // 可选
readonly createdAt: Date;
greet(): string;
}
const u: User = {
id: 1,
name: 'Tom',
createdAt: new Date(),
greet() { return `hi ${this.name}`; }
};
键值结构用索引签名;interface 也能描述函数。
interface Dict {
[key: string]: number;
}
const scores: Dict = {math: 90, english: 85};
interface StringMap<T> {
[key: string]: T;
}
interface CompareFn {
(a: number, b: number): number;
}
const asc: CompareFn = (a, b) => a - b;
type 可给任意类型起名(联合、元组、函数、交叉等)。
type ID = number | string;
type Point = [number, number];
type Callback = (data: string) => void;
type WithId = { id: number };
type Result = { ok: true; value: number }
| { ok: false; error: string };
const r: Result = {ok: true, value: 1};
interface 可重复声明自动合并、适合对象与被类实现;type 表达力更广。
// interface 声明合并
interface Window2 { title: string }
interface Window2 { count: number }
// 等价 { title: string; count: number }
// interface 可 extends / implements
interface Animal { name: string }
interface Dog extends Animal { bark(): void }
// type 用交叉扩展
type Cat = Animal & { meow(): void };
🧬 泛型
用类型参数占位,调用时保留入参与返回值的关联。
function identity<T>(value: T): T {
return value;
}
const n = identity<number>(1);
const s = identity('hi'); // 推断 T = string
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
function pair<T, U>(a: T, b: U): [T, U] {
return [a, b];
}
接口/类/类型都能带类型参数,并可给默认类型。
interface ApiResponse<T = unknown> {
code: number;
message: string;
data: T;
}
type UserResp = ApiResponse<{ id: number; name: string }>;
interface Box<T> {
value: T;
map<U>(fn: (v: T) => U): Box<U>;
}
class Stack<T> {
private items: T[] = [];
push(v: T) { this.items.push(v); }
pop(): T | undefined { return this.items.pop(); }
}
限制类型参数必须具备某些结构;keyof 约束为对象的键。
function len<T extends { length: number }>(arg: T): number {
return arg.length;
}
len('abc'); // OK
len([1, 2]); // OK
function getProp<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
getProp({id: 1, name: 'Tom'}, 'name'); // string
keyof 取对象所有键的联合;typeof 取变量/值的类型。
interface User { id: number; name: string }
type UserKey = keyof User; // 'id' | 'name'
type IdType = User['id']; // number(索引访问类型)
const config = {
host: 'localhost',
port: 3000,
flags: ['a', 'b']
};
type Config = typeof config;
type Port = Config['port']; // number
🔀 联合与交叉
联合只能访问公共成员,需收窄后才能用各自字段。
type Id = number | string;
function format(id: Id): string {
if (typeof id === 'number') {
return 'N' + id.toFixed(0); // 此处 id: number
}
return id.toUpperCase(); // 此处 id: string
}
type Shape =
| { kind: 'circle'; r: number }
| { kind: 'square'; size: number };
function area(s: Shape): number {
switch (s.kind) {
case 'circle': return Math.PI * s.r ** 2;
case 'square': return s.size ** 2;
}
}
& 把多个类型合并为一个,常用于混入公共字段。
type Timestamps = {
createdAt: Date;
updatedAt: Date;
};
type Article = {
id: number;
title: string;
} & Timestamps;
const a: Article = {
id: 1,
title: 'TS 入门',
createdAt: new Date(),
updatedAt: new Date()
};
type Draggable = { drag(): void };
type Resizable = { resize(): void };
type UI = Draggable & Resizable;
🛠 内置工具类型
批量改可选、必填、只读。
interface User { id: number; name: string; email?: string }
type PartialUser = Partial<User>; // 所有字段变可选
type RequiredUser = Required<User>; // 所有字段变必填
type ReadonlyUser = Readonly<User>; // 所有字段只读
function update(id: number, patch: Partial<User>) {}
update(1, { name: 'New' }); // 只传要更新的字段
挑字段、去字段、按键值类型造映射类型,使用频率最高。
type UserPreview = Pick<User, 'id' | 'name'>;
type UserForm = Omit<User, 'id'>;
type Role = 'admin' | 'editor' | 'viewer';
type Perm = Record<Role, boolean>;
// { admin: boolean; editor: boolean; viewer: boolean }
type TableRows = Record<number, User>;
type Env = Record<'dev' | 'prod', { host: string }>;
操作联合类型;从函数类型上提取返回值与参数。
type T = string | number | boolean;
type A = Exclude<T, string>; // number | boolean
type B = Extract<T, string | number>; // string | number
type Non = NonNullable<string | null | undefined>; // string
function createUser(name: string, age: number) {
return { id: 1, name, age };
}
type Ret = ReturnType<typeof createUser>; // {id:number;name:string;age:number}
type Params = Parameters<typeof createUser>; // [string, number]
🔍 类型守卫
typeof 适合原始类型;in 判断对象是否含某属性。
function double(x: number | string) {
if (typeof x === 'number') return x * 2;
return x + x;
}
interface Fish { swim(): void }
interface Bird { fly(): void }
function move(a: Fish | Bird) {
if ('swim' in a) a.swim();
else a.fly();
}
class 实例用 instanceof;可辨识联合用公共字面量字段判别。
if (err instanceof TypeError) {
console.log('类型错误');
} else if (err instanceof Error) {
console.log(err.message);
}
type Event =
| { type: 'click'; x: number; y: number }
| { type: 'keydown'; key: string };
function handle(e: Event) {
if (e.type === 'click') console.log(e.x, e.y);
else console.log(e.key);
}
返回“参数 is 类型”的函数,可在各处复用收窄逻辑。
interface Fish { swim(): void }
function isFish(pet: Fish | { fly(): void }): pet is Fish {
return (pet as Fish).swim !== undefined;
}
const pets: Array<Fish | { fly(): void }> = [];
pets.filter(isFish).forEach(f => f.swim()); // filter 后类型为 Fish[]
function isString(x: unknown): x is string {
return typeof x === 'string';
}
⚡ 断言与函数进阶
告诉编译器“我更清楚类型”;非空断言 ! 表示确定不是 null/undefined。
const el = document.querySelector('#app') as HTMLDivElement;
const input = document.querySelector('input')!;
input.value = 'hi';
const data = JSON.parse(text) as { id: number; name: string };
// 双重断言(类型完全不相关时,尽量避免)
const v = 'x' as unknown as number;
const config = {host: 'localhost'} as const;
// 所有属性变 readonly 且类型为字面量
同一函数多种参数/返回形式,实现签名需兼容所有重载。
function parse(x: string): number;
function parse(x: number): string;
function parse(x: string | number): string | number {
return typeof x === 'string' ? Number(x) : String(x);
}
parse('1'); // number
parse(1); // string
default 分支赋值给 never,漏处理新变体时编译报错。
type Result =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: string }
| { status: 'error'; error: Error };
function render(r: Result): string {
switch (r.status) {
case 'idle': return '';
case 'loading': return '加载中...';
case 'success': return r.data;
case 'error': return r.error.message;
default:
const _exhaustive: never = r;
return _exhaustive;
}
}
⚙️ tsconfig 与命令
target 决定输出语法,module 决定模块系统,strict 强烈建议开启。
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"jsx": "react-jsx",
"sourceMap": true,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
strict: true 是总开关,也可逐项控制严格程度。
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true, // 禁止隐式 any
"strictNullChecks": true, // null/undefined 不能随便赋值
"strictFunctionTypes": true, // 函数类型严格检查
"noUnusedLocals": true, // 未使用变量报错
"noUnusedParameters": true, // 未使用参数报错
"noImplicitReturns": true // 分支有返回有的没返回时报错
}
}
构建工具(vite/ts-node)不做完整类型检查,CI 里应单独跑 tsc --noEmit。
npm i -g typescript
tsc --init # 生成 tsconfig.json
tsc # 按 tsconfig 编译
tsc --noEmit # 只做类型检查不产出
tsc -w # 监听模式
npx tsc app.ts # 不使用配置直接编译
npx tsc --strict --target ES2020 app.ts
😶 没有匹配的条目,换个关键词试试
📖 使用说明
全程在浏览器本地运行。
操作步骤:
- 搜索或浏览分类条目;
- 查看语法与示例代码;
- 点击复制代码块。
💬 用户评论 (0)
还没有评论,快来抢沙发!