typescripe 常见面试题

272 阅读3分钟

以下是 TypeScript 高频面试题的全面总结,结合技术深度与实际应用场景,帮助你系统掌握核心概念。重点涵盖泛型、类型别名(type)与接口(interface)的对比、继承机制等核心内容,并补充高级类型和综合应用案例。

⚙️ 一、泛型(Generics)

泛型是 TS 中创建可复用代码的核心工具,通过参数化类型提升类型安全与代码灵活性。

1. 基本使用场景

  • 函数泛型:避免 any 丢失类型信息

    typescript

    function identity<T>(arg: T): T { return arg; }
    const num = identity<number>(10); // 明确类型为 number
    
  • 类泛型:复用类逻辑

    typescript

    class Collection<T> {
        private data: T[] = [];
        push(item: T) { this.data.push(item); }
    }
    const numbers = new Collection<number>();
    
  • 接口泛型:动态定义结构

    typescript

    interface ApiResponse<T> {
        data: T;
        code: number;
    }
    

2. 泛型约束(extends

限制泛型范围,避免操作不存在的属性:

typescript

// 约束 T 必须包含 length 属性
function getLength<T extends { length: number }>(obj: T): number {
    return obj.length;
}
getLength("abc"); // ✅ 3
getLength([1, 2]); // ✅ 2
getLength(10); // ❌ 编译报错

3. keyof 操作符

动态获取对象键的类型集合:

typescript

type Person = { name: string; age: number };
type PersonKeys = keyof Person; // "name" | "age"
function getValue<T, K extends keyof T>(obj: T, key: K) {
    return obj[key]; // 类型安全
}

二、type vs interface 深度对比

1. 核心差异总结

特性interfacetype
声明合并✅ 支持同名自动合并❌ 禁止重复声明
扩展语法extends 关键字& 交叉类型
描述类型范围对象/函数类型任意类型(联合、元组、基本类型等)
类实现(implements✅ 直接支持✅ 仅限对象类型(非联合类型)
工具类型支持❌ 不支持条件类型等✅ 支持映射类型、条件类型等高级操作
错误提示保留接口名(更清晰)可能展开为具体类型(较冗长)

2. 关键场景选择

  • 用 interface 的场景

    • 面向对象设计(类实现接口)

    • 需要声明合并(扩展第三方库类型)

    • 公共 API 定义(错误提示友好)

      typescript

      interface ButtonProps { label: string; }
      interface ButtonProps { color: string; } // 自动合并
      
  • 用 type 的场景

    • 联合类型(type Status = 'success' | 'error'

    • 元组(type Coord = [number, number]

    • 复杂类型运算(条件类型、映射类型)

      typescript

      type Partial<T> = { [P in keyof T]?: T[P] };
      

三、继承与实现(Inheritance & Implementation)

1. 类继承(extends

子类复用父类逻辑与方法:

typescript

class Animal { move() { /* ... */ } }
class Dog extends Animal { bark() { /* ... */ } }
const dog = new Dog();
dog.move(); // 继承父类方法

2. 接口继承

  • interface 继承:用 extends 扩展

    typescript

    interface Shape { color: string; }
    interface Circle extends Shape { radius: number; }
    
  • type 继承:用 & 交叉类型

    typescript

    type Shape = { color: string };
    type Circle = Shape & { radius: number };
    

3. 类实现接口(implements

强制类符合接口契约:

typescript

interface ClockInterface { currentTime: Date; }
class Clock implements ClockInterface {
    currentTime = new Date(); // 必须实现接口成员
}

注意:类不能实现联合类型(type U = A | B


🔮 四、高级类型与综合应用

1. 条件类型(Conditional Types)

根据输入类型动态推导输出类型:

typescript

type IsString<T> = T extends string ? "Yes" : "No";
type Result = IsString<"hello">; // "Yes"

2. React 中的泛型问题

解决 forwardRef 与泛型组件的冲突:

typescript

// 自定义高阶组件保留泛型
const withForwardRef = <T, R>(Component: React.ComponentType<T>) => {
  return React.forwardRef<R, T>((props, ref) => 
     <Component {...props} innerRef={ref} />
  );
};

3. 类型推断(infer

在条件类型中提取局部类型:

typescript

type UnpackArray<T> = T extends (infer U)[] ? U : T;
type NumType = UnpackArray<number[]>; // number

🧩 五、综合示例:泛型 + 接口 + 继承

typescript

// 定义基础接口
interface Entity { id: number; }

// 泛型仓库类(使用约束)
class Repository<T extends Entity> {
    private items: T[] = [];
    add(item: T) { this.items.push(item); }
    getById(id: number): T | undefined {
        return this.items.find(item => item.id === id);
    }
}

// 具体实体类
interface User extends Entity { name: string; }
const userRepo = new Repository<User>();
userRepo.add({ id: 1, name: "Alice" }); // ✅ 类型安全

💎 最佳实践总结

  1. 泛型使用场景:函数/类复用逻辑时优先使用,避免 any 丢失类型59。

  2. interface vs type

    • 公共 API、类实现 → interface
    • 联合类型、工具类型 → type 46。
  3. 扩展方式

    • 接口继承 → extends
    • 类型扩展 → & 交叉类型 810。
  4. 性能提示:大型项目避免深层嵌套 type,可能影响编译速度4。

此总结覆盖了 90% 的 TS 面试考点,建议重点理解泛型约束、type 与 interface 的取舍、类与接口的协作模式。实际编码中,一致性比选择更重要——团队统一规范即可。