MST

星途 面试题库

面试题:TypeScript中Record工具类型在大型项目架构中的深度应用及优化

在一个大型前端项目中,有多个模块,每个模块都有自己的配置对象。模块的名称作为键,配置对象作为值。配置对象的结构会根据模块不同而变化,但都有一个公共的`baseConfig`属性,类型为`{enabled: boolean}`。请基于Record工具类型设计一个类型系统,满足以下需求:1. 能灵活定义每个模块配置对象的额外属性;2. 能方便地添加新模块及对应的配置;3. 对类型检查和代码提示友好,并且在性能上尽可能优化,减少不必要的类型计算。请详细阐述设计思路并给出关键代码示例。
12.2万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 使用Record工具类型Record工具类型可以方便地定义以某个类型为键,另一个类型为值的对象类型。在这里,键是模块名称(可以是字符串字面量类型或联合类型),值是每个模块对应的配置对象。
  2. 定义公共属性baseConfig:通过接口或类型别名定义包含enabled属性的公共部分baseConfig,每个模块的配置对象都继承这个公共部分。
  3. 灵活定义额外属性:为每个模块单独定义类型,这些类型扩展公共部分,并添加各自的额外属性。
  4. 方便添加新模块:由于使用了Record,只需在联合类型中添加新的模块名称,并定义对应的配置类型即可。
  5. 性能优化:避免复杂的递归类型或过度的类型计算,保持类型简洁明了。

关键代码示例

// 定义公共的baseConfig类型
interface BaseConfig {
    enabled: boolean;
}

// 定义模块A的配置类型
interface ModuleAConfig extends BaseConfig {
    extraPropA: string;
}

// 定义模块B的配置类型
interface ModuleBConfig extends BaseConfig {
    extraPropB: number;
}

// 使用Record工具类型定义整体配置类型
type ModuleConfigs = Record<'moduleA' |'moduleB', ModuleAConfig | ModuleBConfig>;

// 示例配置对象
const config: ModuleConfigs = {
    moduleA: {
        enabled: true,
        extraPropA: 'example value'
    },
    moduleB: {
        enabled: false,
        extraPropB: 42
    }
};

这样,在添加新模块时,例如模块moduleC

// 定义模块C的配置类型
interface ModuleCConfig extends BaseConfig {
    extraPropC: boolean;
}

// 更新ModuleConfigs类型
type ModuleConfigs = Record<'moduleA' |'moduleB' |'moduleC', ModuleAConfig | ModuleBConfig | ModuleCConfig>;

// 示例配置对象更新
const config: ModuleConfigs = {
    moduleA: {
        enabled: true,
        extraPropA: 'example value'
    },
    moduleB: {
        enabled: false,
        extraPropB: 42
    },
    moduleC: {
        enabled: true,
        extraPropC: false
    }
};