Typescript 面试题目整理

3/13/2026 typescriptinterview

# 🎯 Typescript 面试题目整理

# 1. 什么是泛型?

泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。

核心优势:

  • 代码复用:同一套逻辑可用于多种类型
  • 类型安全:编译时进行类型检查
  • 灵活性:保持类型约束的同时提供灵活性

常见应用场景:

// 1. 泛型函数
function identity<T>(arg: T): T {
  return arg;
}

const num = identity<number>(123); // 显式指定
const str = identity('hello'); // 类型推断

// 2. 泛型接口
interface Box<T> {
  value: T;
}

const box: Box<string> = { value: 'test' };

// 3. 泛型类
class GenericNumber<T> {
  zeroValue: T;
  add: (x: T, y: T) => T;
}

// 4. 泛型约束
interface Lengthwise {
  length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length);
  return arg;
}

// 5. 常用工具泛型
// Partial<T> - 所有属性变为可选
// Required<T> - 所有属性变为必需
// Readonly<T> - 所有属性变为只读
// Pick<T, K> - 选取部分属性
// Omit<T, K> - 排除部分属性

# 2. type 和 interface 的区别

特性 interface type
定义方式 interface Person { } type Person = { }
扩展方式 extends 关键字 交叉类型 &
合并行为 支持声明合并 不支持
适用范围 只能定义对象结构 可定义任何类型(联合、元组、基本类型等)

关键区别详解:

// 1. 声明合并(interface 独有)
interface User {
  name: string;
}

interface User {
  age: number;
}
// 合并为:{ name: string; age: number; }

// type 会报重复定义错误
type Animal = { species: string };
// type Animal = { legs: number };  // ❌ Error

// 2. 扩展语法不同
interface Animal {
  name: string;
}

interface Dog extends Animal {
  breed: string;
}

// 使用 type 实现类似效果
type Person = { name: string };
type Employee = Person & { role: string }; // 交叉类型

// 3. type 能定义更丰富的类型
type StringOrNumber = string | number; // 联合类型
type Pair = [string, number]; // 元组类型
type Direction = 'up' | 'down' | 'left'; // 字面量类型
type GetName = () => string; // 函数类型

// interface 只能定义对象形状
// interface GetName = () => string;  // ❌ Error

使用建议:

  • 定义对象结构、需要声明合并 → 用 interface
  • 定义联合类型、元组、函数类型等复杂类型 → 用 type
  • 很多场景下两者可以互换,保持代码库一致性更重要

# 3. any、unknown、never 的区别

这三个类型代表了 TypeScript 中类型安全的三个极端:

# any - 类型系统中的"后门"

let anything: any = 42;
anything = 'hello'; // ✅ 可以赋任何值
anything.foo.bar; // ✅ 任意属性访问
anything(); // ✅ 任意调用
anything[0][1]; // ✅ 任意索引访问
  • 特点:完全放弃类型检查,可以赋值给任何类型
  • 用途:逐步迁移 JS 项目、处理动态数据
  • 风险:破坏类型安全,应尽量避免使用

# unknown - 类型安全的 any

let value: unknown = 42;

value = 'hello'; // ✅ 可以赋任何值

// value.foo.bar;          // ❌ Error: 必须先收窄类型
// value();                // ❌ Error: 必须先收窄类型

// 使用前必须进行类型检查
if (typeof value === 'string') {
  console.log(value.toUpperCase()); // ✅ TypeScript 知道这里是 string
}

// 类型断言/收窄
const str = value as string; // ⚠️ 需要自己保证正确
  • 特点:可以接受任何值,但使用前必须确定类型
  • 用途:处理不确定类型的数据、API 返回值
  • 优势:强制开发者做类型检查,比 any 更安全

# never - 不可能存在的类型

// 1. 永不返回的函数
function throwError(message: string): never {
  throw new Error(message);
}

function infiniteLoop(): never {
  while (true) {}
}

// 2. 类型收窄的终点
function getArea(shape: Shape) {
  switch (shape.type) {
    case 'circle':
      return Math.PI * shape.radius ** 2;
    case 'square':
      return shape.side ** 2;
    default:
      const _exhaustiveCheck: never = shape; // ✅ 确保处理所有情况
      return _exhaustiveCheck;
  }
}

// 3. 空数组类型推断
const emptyArray = []; // 类型为 never[]
emptyArray.push(1); // ✅ 推断为 number[]
  • 特点:表示永远不存在的值类型
  • 用途:抛异常函数、死循环、穷尽类型检查
  • 特性:never 是所有类型的子类型,可以赋值给任何类型

# 三者关系图

类型范围:
┌─────────────────────────────────────┐
│           any (最宽泛)               │
│  ┌───────────────────────────────┐  │
│  │    unknown (安全的最宽泛)       │  │
│  │   ┌─────────────────────────┐  │  │
│  │   │   具体类型 (string, etc) │  │  │
│  │   │   ┌───────────────────┐  │  │  │
│  │   │   │   never (最窄)     │  │  │  │
│  │   │   └───────────────────┘  │  │  │
│  │   └─────────────────────────┘  │  │
│  └───────────────────────────────┘  │
└─────────────────────────────────────┘

赋值关系:
any      ← never ✅  (never 可赋值给任何类型)
unknown  ← never ✅
string   ← never ✅

any ← unknown ❌  (unknown 不能赋值给 any 以外的类型)
any ← string  ❌

最佳实践:

// ❌ 避免 any
function processData(data: any) {}

// ✅ 优先 unknown
function processData(data: unknown) {
  if (isValidData(data)) {
    // 使用 data
  }
}

// ✅ never 用于穷尽检查
type Shape = Circle | Square;
function assertNever(x: never): never {
  throw new Error('Unexpected object: ' + x);
}

# 4. 什么是类型断言

类型断言就是"我比你更懂这个值的类型,听我的"

// 方法1:as 写法(推荐)
let value = 'hello' as string;

// 方法2:尖括号写法
let value = <string>'hello';

// 什么时候用
// DOM 元素操作、处理 API 返回数据、处理联合类型、非空断言、const 断言(类型变成:readonly)

// 1. DOM 操作
document.getElementById('id') as HTMLDivElement;

// 2. 接口数据
fetch(url).then((res) => res.json() as User)

// 3. 确定非空
// 可能为空的变量!

// 4. 精确类型
['a', 'b'] as const

# 5. 用 ts 实现多态,父类 animal,子类 cat 和 dog,包含 name 属性,实现 say 方法

class Animal {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  say(): void {
    console.log('Animal says...');
  }
}

class Cat extends Animal {
  say(): void {
    console.log('Meow!');
  }
}

class Dog extends Animal {
  say(): void {
    console.log('Woof!');
  }
}

// 多态性的应用
const animals: Animal[] = [new Cat('Tom'), new Dog('Max'), new Cat('Kitty')];

animals.forEach((animal) => {
  console.log(`Name: ${animal.name}`);
  animal.say();
  console.log('------------------');
});

// yarn add global ts-node typescript
// npx ts-node test.ts