以下是 TypeScript(TS)常见的面试题分类及参考答案,覆盖基础语法、类型系统、高级特性等核心知识点:
一、基础概念
1. TypeScript 与 JavaScript 的区别?
- TypeScript:JavaScript 的超集,静态类型检查,提供接口、枚举、类等面向对象特性,编译后生成纯 JS 代码。
- JavaScript:动态类型,无编译时类型检查,灵活性高但容易出现运行时错误。
2. 什么是静态类型和动态类型?
- 静态类型:编译时检查类型,如 TS、Java;
- 动态类型:运行时检查类型,如 JS、Python。
二、类型系统
1. 如何定义基本类型?
typescript
ini
let num: number = 10;
let str: string = 'hello';
let isDone: boolean = false;
let arr: number[] = [1, 2, 3]; // 或 Array<number>
let tuple: [string, number] = ['a', 1]; // 元组
2. 什么是联合类型(Union Type)和交叉类型(Intersection Type)?
- 联合类型 :
A | B
,值可以是 A 或 B 类型(如string | number
)。 - 交叉类型 :
A & B
,值同时拥有 A 和 B 的所有属性(常用于接口合并)。
3. 如何实现类型守卫(Type Guard)?
- typeof :判断基本类型(如
typeof x === 'string'
)。 - instanceof :判断类实例(如
x instanceof Person
)。 - 自定义守卫 :通过函数返回类型谓词(如
function isString(x: any): x is string
)。
三、接口与类
1. 接口(Interface)和类型别名(Type Alias)的区别?
- 接口 :只能定义对象结构,支持继承(
extends
),自动合并同名接口。 - 类型别名 :可定义基本类型、联合类型等,通过
&
合并类型,不可重复定义。
2. 如何实现类的继承和多态?
typescript
typescript
class Animal {
constructor(protected name: string) {}
speak(): string { return 'Animal sound'; }
}
class Dog extends Animal {
speak(): string { return `Dog ${this.name} barks`; } // 重写方法
}
const dog: Animal = new Dog('Buddy');
console.log(dog.speak()); // 多态:输出 "Dog Buddy barks"
四、高级特性
1. 泛型(Generics)的作用?
-
示例:
typescript
csharpfunction identity<T>(arg: T): T { return arg; } const num = identity<number>(10); // 或省略类型参数,自动推断
-
作用:创建可复用组件,支持多种数据类型,避免重复代码。
2. 什么是装饰器(Decorator)?
-
示例:
typescript
typescriptfunction log(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; descriptor.value = function(...args: any[]) { console.log(`Calling ${propertyKey} with ${args}`); return originalMethod.apply(this, args); }; } class Calculator { @log add(a: number, b: number) { return a + b; } }
-
作用:在不修改原代码的情况下,扩展类、方法、属性的功能。
3. 如何处理可选链(Optional Chaining)和空值合并(Nullish Coalescing)?
- 可选链 :
obj?.prop
或obj?.method()
,避免obj.prop
因obj
为null/undefined
报错。 - 空值合并 :
a ?? b
,仅当a
为null/undefined
时返回b
(区别于||
)。
五、类型体操
1. 如何实现 Partial<T>
工具类型?
typescript
ini
type Partial<T> = { [P in keyof T]?: T[P] }; // 将所有属性变为可选
2. 如何获取函数返回值类型?
typescript
typescript
type ReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : never;
function fetchData(): Promise<string> { return Promise.resolve('data'); }
type Data = ReturnType<typeof fetchData>; // 类型为 Promise<string>
六、工程实践
1. tsconfig.json 中常见配置项的作用?
-
compilerOptions:
target
:指定 JS 版本(如ESNext
)。module
:指定模块系统(如ESNext
)。strict
:启用所有严格类型检查(如noImplicitAny
)。outDir
:编译输出目录。moduleResolution
:模块解析策略(如Node
)。
2. 如何处理第三方库的类型声明?
-
安装官方类型包:
npm install @types/xxx
。 -
自定义类型声明文件(
.d.ts
):typescript
typescriptdeclare module 'library-name' { export function func(): string; }
七、常见场景
1. 如何处理异步函数的返回类型?
typescript
csharp
async function getData(): Promise<string> {
return 'data';
}
// 使用时需考虑 Promise 包装
const result: string = await getData(); // 正确
const wrong: string = getData(); // 错误,类型为 Promise<string>
2. 如何在 React 中使用 TypeScript?
tsx
typescript
import React, { FC, useState } from 'react';
interface Props {
name: string;
age?: number;
}
const App: FC<Props> = ({ name, age = 18 }) => {
const [count, setCount] = useState<number>(0);
return <div>Hello {name}, age {age}, count {count}</div>;
};
八、设计模式
1. 如何实现单例模式(Singleton)?
typescript
csharp
class Singleton {
private static instance: Singleton;
private constructor() {} // 私有构造函数
static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
九、性能优化
1. TypeScript 会影响运行时性能吗?
- 编译后:TS 代码被编译为纯 JS,不会影响运行时性能。
- 编译时 :类型检查会增加构建时间,但可通过
tsconfig.json
配置优化(如incremental
选项)。
十、易错点
1. any
和 unknown
的区别?
any
:禁用类型检查,可赋值给任意类型。unknown
:安全的 "未知类型",使用前必须先断言或类型守卫。
2. 如何避免类型断言滥用?
- 优先使用类型守卫或泛型。
- 仅在确定类型但编译器无法推断时使用断言(如
as Type
)。