Appearance
TS 高频面试题(新手必备)
TS 与 JS 区别
核心区别
- 类型系统:TypeScript 是 JavaScript 的超集,添加了静态类型系统
- 编译阶段:TypeScript 需要编译成 JavaScript 才能在浏览器中运行
- 开发体验:TypeScript 提供更好的代码提示、类型检查和重构工具
- 生态系统:TypeScript 与 JavaScript 生态系统完全兼容,但提供了额外的类型定义
代码示例
typescript
// JavaScript
define function without types
function add(a, b) {
return a + b;
}
// TypeScript
define function with types
function add(a: number, b: number): number {
return a + b;
}any 与 unknown 区别
any 类型
- 特点:完全关闭类型检查,允许任何操作
- 风险:失去 TypeScript 的类型安全优势
- 使用场景:当确实不知道类型且无法推断时
unknown 类型
- 特点:安全的 any,需要类型检查才能使用
- 优势:保持类型安全,强制类型检查
- 使用场景:接收未知类型的输入,需要进行类型守卫
代码示例
typescript
// any 类型 - 不安全
let anyValue: any = "hello";
anyValue(); // 不会报错,但运行时会失败
// unknown 类型 - 安全
let unknownValue: unknown = "hello";
// unknownValue(); // 编译时报错
if (typeof unknownValue === "function") {
unknownValue(); // 类型守卫后可以使用
}interface 与 type 区别
相似点
- 都可以定义对象结构
- 都可以用于类型注解
不同点
- interface:只能定义对象类型,支持合并声明,支持 extends 继承
- type:可以定义任何类型(包括基本类型、联合类型等),不支持合并声明,使用 & 交叉类型
代码示例
typescript
// interface
interface User {
name: string;
age: number;
}
// 合并声明
interface User {
email: string;
}
// type
type User = {
name: string;
age: number;
};
// 交叉类型
type AdminUser = User & {
role: string;
};泛型作用
核心作用
- 代码复用:创建可重用的组件,支持多种类型
- 类型安全:在编译时提供类型检查
- 灵活性:不牺牲类型安全的前提下提供灵活性
代码示例
typescript
// 泛型函数
function identity<T>(arg: T): T {
return arg;
}
// 泛型接口
interface GenericArray<T> {
length: number;
push: (item: T) => void;
}
// 泛型类
class Stack<T> {
private items: T[] = [];
push(item: T) {
this.items.push(item);
}
pop(): T | undefined {
return this.items.pop();
}
}常用工具类型
- Partial< T>:将所有属性变为可选
- Required< T>:将所有属性变为必选
- Readonly< T>:将所有属性变为只读
- Pick< T, K>:从 T 中挑选属性 K
- Omit< T, K>:从 T 中剔除属性 K
- Exclude< T, U>:从 T 中排除 U 类型
- Extract< T, U>:从 T 中提取 U 类型
- ReturnType< T>:获取函数返回值类型
- Record< K, T>:创建键为 K,值为 T 的对象类型
代码示例
typescript
interface User {
name: string;
age: number;
email: string;
}
// Partial<T>
type PartialUser = Partial<User>;
// Required<T>
type RequiredUser = Required<User>;
// Readonly<T>
type ReadonlyUser = Readonly<User>;
// Pick<T, K>
type PickUser = Pick<User, "name" | "email">;
// Omit<T, K>
type OmitUser = Omit<User, "age">;枚举、元组、联合类型使用场景
枚举(Enum)
- 使用场景:表示一组固定的常量值,如状态码、方向等
- 优势:提高代码可读性,避免魔法数字
元组(Tuple)
- 使用场景:表示固定长度和类型的数组,如坐标、RGB 颜色等
- 优势:提供精确的类型检查
联合类型(Union Type)
- 使用场景:表示值可以是多种类型之一,如函数参数、返回值等
- 优势:增加类型灵活性
代码示例
typescript
// 枚举
enum Direction {
Up,
Down,
Left,
Right
}
// 元组
let point: [number, number] = [10, 20];
// 联合类型
let value: string | number | boolean = "hello";为什么要禁用 any?
主要原因
- 失去类型安全:any 类型关闭了 TypeScript 的类型检查
- 代码质量下降:无法利用 TypeScript 的类型推断和提示
- 维护成本增加:类型错误会在运行时才暴露
- 团队协作困难:无法清晰理解代码的类型结构
替代方案
- 使用 unknown 类型接收未知输入
- 使用 联合类型 明确可能的类型
- 使用 类型断言 配合类型守卫
- 为第三方库编写类型定义
