面试题答案
一键面试设计思路
- 使用
Record
工具类型:Record
工具类型可以方便地定义以某个类型为键,另一个类型为值的对象类型。在这里,键是模块名称(可以是字符串字面量类型或联合类型),值是每个模块对应的配置对象。 - 定义公共属性
baseConfig
:通过接口或类型别名定义包含enabled
属性的公共部分baseConfig
,每个模块的配置对象都继承这个公共部分。 - 灵活定义额外属性:为每个模块单独定义类型,这些类型扩展公共部分,并添加各自的额外属性。
- 方便添加新模块:由于使用了
Record
,只需在联合类型中添加新的模块名称,并定义对应的配置类型即可。 - 性能优化:避免复杂的递归类型或过度的类型计算,保持类型简洁明了。
关键代码示例
// 定义公共的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
}
};