MST

星途 面试题库

面试题:TypeScript 如何处理从 JavaScript 迁移过程中的类型兼容问题?

假设你正在将一个大型的 JavaScript 项目迁移到 TypeScript,在迁移过程中,如何逐步添加类型注释以确保代码的类型安全,同时不影响原有 JavaScript 代码的功能?举例说明如何处理一些常见的类型兼容场景,比如函数重载、接口合并等。
36.6万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

逐步添加类型注释确保代码类型安全且不影响原有功能的方法

  1. 文件逐个迁移:从项目中较小、独立且关键的 JavaScript 文件开始,将其重命名为 .ts.tsx 文件。例如,先选择工具函数文件,因为它们通常与其他模块耦合度较低。然后逐步为函数参数、返回值添加类型注释。
  2. 使用 // @ts-check:在 JavaScript 文件顶部添加 // @ts-check,这样 TypeScript 会以宽松模式对该文件进行类型检查。可以逐步根据检查提示添加类型注释,如对于变量 let num;,若提示缺少类型,可添加 let num: number;
  3. 渐进式迁移模块:对于依赖关系复杂的模块,可先为导出的函数和接口添加类型注释,确保外部调用的类型安全。随着迁移深入,再逐步完善模块内部代码的类型注释。

常见类型兼容场景处理

函数重载

在 JavaScript 中,一个函数可能根据传入参数的不同执行不同逻辑。例如:

function add(a, b) {
    if (typeof a ==='string' && typeof b ==='string') {
        return a + b;
    } else if (typeof a === 'number' && typeof b === 'number') {
        return a + b;
    }
}

在 TypeScript 中实现函数重载:

function add(a: string, b: string): string;
function add(a: number, b: number): number;
function add(a: string | number, b: string | number): string | number {
    if (typeof a ==='string' && typeof b ==='string') {
        return a + b;
    } else if (typeof a === 'number' && typeof b === 'number') {
        return a + b;
    }
    return '';
}

这里先定义了两个重载签名,然后是实现签名,实现签名要包含所有可能的参数和返回值类型。

接口合并

在 JavaScript 项目中,可能会有一个对象,在不同地方对其属性进行扩展。例如:

let obj = {};
obj.name = 'John';
obj.age = 30;

在 TypeScript 中使用接口合并来处理:

interface User {
    name: string;
}
interface User {
    age: number;
}
let obj: User = {};
obj.name = 'John';
obj.age = 30;

通过定义多个同名接口,TypeScript 会自动合并它们的属性,确保对象类型的完整性。