🔷
TypeScript
12 道题目
难度筛选:
相同点:
• 都能描述对象形状
• 都能扩展(type 用
区别:
1. type 可以联合类型、基本类型、元组:
2. interface 可以声明合并:同名 interface 自动合并(适合扩展第三方类型)
3. type 支持映射类型和条件类型
建议:描述对象结构用 interface(支持合并),其他用 type。团队统一即可。
• 都能描述对象形状
• 都能扩展(type 用
&,interface 用 extends)区别:
1. type 可以联合类型、基本类型、元组:
type T = string | number2. interface 可以声明合并:同名 interface 自动合并(适合扩展第三方类型)
3. type 支持映射类型和条件类型
建议:描述对象结构用 interface(支持合并),其他用 type。团队统一即可。
查看答案即标记为已答
泛型允许在定义时不指定具体类型,使用时再确定,提高代码复用性。
函数泛型:
接口泛型:
泛型约束:
常用场景:API 响应封装、工具函数、React 组件 Props 类型。
函数泛型:
function identity<T>(arg: T): T { return arg; }接口泛型:
interface ApiResponse<T> { code: number; data: T; }泛型约束:
function getLength<T extends { length: number }>(arg: T): number { return arg.length; }常用场景:API 响应封装、工具函数、React 组件 Props 类型。
查看答案即标记为已答
1. Partial<T> — 所有属性变可选
2. Required<T> — 所有属性变必填
3. Readonly<T> — 所有属性只读
4. Pick<T, K> — 从 T 中选取部分属性
5. Omit<T, K> — 从 T 中排除部分属性
6. Record<K, V> — 键值对类型
7. Exclude<T, U> — 从联合类型中排除
8. Extract<T, U> — 从联合类型中提取
9. ReturnType<T> — 获取函数返回值类型
10. Parameters<T> — 获取函数参数类型元组
实现原理示例:
2. Required<T> — 所有属性变必填
3. Readonly<T> — 所有属性只读
4. Pick<T, K> — 从 T 中选取部分属性
5. Omit<T, K> — 从 T 中排除部分属性
6. Record<K, V> — 键值对类型
7. Exclude<T, U> — 从联合类型中排除
8. Extract<T, U> — 从联合类型中提取
9. ReturnType<T> — 获取函数返回值类型
10. Parameters<T> — 获取函数参数类型元组
实现原理示例:
type Partial<T> = { [K in keyof T]?: T[K] };type Pick<T, K extends keyof T> = { [P in K]: T[P] }; 查看答案即标记为已答
any:放弃类型检查,任何操作都允许(不推荐)
unknown:安全版的 any,必须先收窄类型才能操作
never:不可能存在的类型
• 函数抛异常或无限循环时返回 never
• 联合类型收窄到空时变为 never
• 常用于 exhaustive check(穷举检查)
建议:避免 any,优先 unknown;用 never 做类型守卫。
unknown:安全版的 any,必须先收窄类型才能操作
let val: unknown = 'hello';
val.toUpperCase(); // ❌ 报错
if (typeof val === 'string') { val.toUpperCase(); } // ✅never:不可能存在的类型
• 函数抛异常或无限循环时返回 never
• 联合类型收窄到空时变为 never
• 常用于 exhaustive check(穷举检查)
建议:避免 any,优先 unknown;用 never 做类型守卫。
查看答案即标记为已答
枚举(enum):
• 运行时生成真实对象
• 支持反向映射(数字枚举)
联合类型:
• 零运行时开销
• 更好的 tree-shaking
建议:字符串值优先用联合类型;需要运行时对象或反向映射时用 enum。常量枚举
enum Status { Active, Inactive, Pending }
const s: Status = Status.Active;• 运行时生成真实对象
• 支持反向映射(数字枚举)
联合类型:
type Status = 'active' | 'inactive' | 'pending';
const s: Status = 'active';• 零运行时开销
• 更好的 tree-shaking
建议:字符串值优先用联合类型;需要运行时对象或反向映射时用 enum。常量枚举
const enum 是折中方案。 查看答案即标记为已答
条件类型:根据类型条件返回不同类型
infer:在条件类型中推断类型变量
infer 还能推断数组元素和 Promise 值:
应用:类型体操核心,实现各种高级类型转换。
type IsString<T> = T extends string ? 'yes' : 'no';
type A = IsString<string>; // 'yes'
type B = IsString<number>; // 'no'infer:在条件类型中推断类型变量
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;type Parameters<T> = T extends (...args: infer P) => any ? P : never;infer 还能推断数组元素和 Promise 值:
type ElementOf<T> = T extends (infer E)[] ? E : never;type Awaited<T> = T extends Promise<infer V> ? Awaited<V> : T;应用:类型体操核心,实现各种高级类型转换。
查看答案即标记为已答
声明文件:描述 JavaScript 模块的类型信息,不包含实现。
使用场景:
1. 为没有类型的第三方 JS 库提供类型(如
2. 项目中 JS 和 TS 混用时声明类型
3. 全局变量声明
全局声明:
模块声明:
建议:优先从 DefinitelyTyped 安装
使用场景:
1. 为没有类型的第三方 JS 库提供类型(如
@types/lodash)2. 项目中 JS 和 TS 混用时声明类型
3. 全局变量声明
全局声明:
declare const API_BASE: string;
declare function $(): HTMLElement;模块声明:
declare module 'my-lib' {
export function doSomething(val: string): number;
}建议:优先从 DefinitelyTyped 安装
@types/xxx,没有再手写。 查看答案即标记为已答
类型守卫:在运行时检查以确保类型在某个范围内,让 TypeScript 能收窄类型。
1. typeof:
2. instanceof:
3. in 操作符:
4. 自定义类型谓词:
5. 可辨识联合(Discriminated Union):
1. typeof:
function fn(x: string | number) {
if (typeof x === 'string') { x.toUpperCase(); } // x: string
}2. instanceof:
if (err instanceof TypeError) { err.message; }3. in 操作符:
if ('swim' in animal) { animal.swim(); } // Fish4. 自定义类型谓词:
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}5. 可辨识联合(Discriminated Union):
type Shape = { kind: 'circle'; r: number } | { kind: 'rect'; w: number; h: number };
function area(s: Shape) {
switch (s.kind) {
case 'circle': return Math.PI * s.r ** 2;
case 'rect': return s.w * s.h;
}
} 查看答案即标记为已答
映射类型:基于旧类型构造新类型,通过遍历 key 来转换属性。
基础语法:
修饰符操作:
•
•
键的重映射(TS 4.1+):
过滤属性:
应用:实现 Partial、Required、Pick、Omit 等工具类型的基础。
基础语法:
type Readonly<T> = { readonly [K in keyof T]: T[K] };修饰符操作:
•
+ 添加修饰符(默认)•
- 移除修饰符type Mutable<T> = { -readonly [K in keyof T]: T[K] }; // 移除 readonly
type Optional<T> = { [K in keyof T]?: T[K] }; // 添加 ?
type Required<T> = { [K in keyof T]-?: T[K] }; // 移除 ?键的重映射(TS 4.1+):
type Getters<T> = { [K in keyof T as 'get' + Capitalize<K & string>]: () => T[K] };
// { getName: () => string; getAge: () => number }过滤属性:
type RemoveNull<T> = { [K in keyof T as T[K] extends null ? never : K]: T[K] };应用:实现 Partial、Required、Pick、Omit 等工具类型的基础。
查看答案即标记为已答
类型推断:TypeScript 编译器自动推断变量/函数的类型,无需手动标注。
1. 变量初始化:
2. 函数返回值:
3. 结构类型:
4. 上下文推断:
最佳实践:
• 简单变量:让 TS 推断,不标注
• 函数参数:必须标注
• 复杂返回值:建议标注(文档作用)
• 使用
1. 变量初始化:
let x = 10; // 推断为 number
let name = 'hello'; // 推断为 string
let arr = [1, 'a']; // 推断为 (number | string)[]2. 函数返回值:
function add(a: number, b: number) { return a + b; } // 推断返回 number3. 结构类型:
const obj = { x: 10, y: 'hi' }; // { x: number; y: string }4. 上下文推断:
window.addEventListener('click', (e) => { e.clientX }); // e 推断为 MouseEvent最佳实践:
• 简单变量:让 TS 推断,不标注
• 函数参数:必须标注
• 复杂返回值:建议标注(文档作用)
• 使用
satisfies 运算符确保类型正确但保留推断 查看答案即标记为已答
协变(Covariance):子类型关系与泛型参数方向一致。
逆变(Contravariance):子类型关系与泛型参数方向相反。
TypeScript 函数参数的严格模式:
简单记忆:
• 函数返回值 → 协变(子→父 可以)
• 函数参数 → 逆变(父→子 可以)
• "函数参数类型需要更宽泛才能安全接收"
Dog extends Animal → Dog[] 是 Animal[] 的子类型(协变)逆变(Contravariance):子类型关系与泛型参数方向相反。
(a: Animal) => void 是 (a: Dog) => void 的子类型(函数参数逆变)TypeScript 函数参数的严格模式:
// strictFunctionTypes: true 时参数是逆变的
type Fn1 = (a: Animal) => void;
type Fn2 = (a: Dog) => void;
let f1: Fn1 = (a) => {};
let f2: Fn2 = f1; // ✅ Animal 能接收 Dog
let f3: Fn1 = f2; // ❌ Dog 不能接收所有 Animal简单记忆:
• 函数返回值 → 协变(子→父 可以)
• 函数参数 → 逆变(父→子 可以)
• "函数参数类型需要更宽泛才能安全接收"
查看答案即标记为已答
satisfies(TypeScript 4.9+):验证表达式是否符合某个类型,但不改变推断类型。
问题场景:
用 satisfies 解决:
vs 类型标注:
•
•
适合场景:配置对象、常量映射、确保结构正确同时保留类型精度。
问题场景:
const palette: Record<string, [number, number, number] | string> = {
red: [255, 0, 0],
green: '#00ff00',
};
palette.red.map(...); // ❌ TS 认为可能是 string,不能 map用 satisfies 解决:
const palette = {
red: [255, 0, 0],
green: '#00ff00',
} satisfies Record<string, [number, number, number] | string>;
palette.red.map(...); // ✅ TS 知道 red 是 [number, number, number]vs 类型标注:
•
: Type — 类型变为 Type,丢失具体信息•
satisfies Type — 只验证,保留原始推断类型适合场景:配置对象、常量映射、确保结构正确同时保留类型精度。
查看答案即标记为已答