TypeScript如何让配置项is字段支持父类及其所有继承子类
问题原因
你当前的泛型写法将U定义为全局共享的单一类型,TypeScript会强制所有配置项的is字段必须为同一个类,自然无法兼容ClassA和它的多个子类同时传入的场景。
修复方案
调整泛型逻辑,对每个配置项单独做类型约束即可,修改后的完整代码如下:
class ClassA { foo: string constructor(options: {foo: string}) { this.foo = options.foo } } class ClassB extends ClassA { constructor(options: {bar: number}) { super({foo: ''}) } } // 直接在泛型中做映射约束,每个配置项独立匹配is和对应的options类型 function create<T extends Record<string, { is: new (...args: any[]) => ClassA }>>(config: { classes: { [K in keyof T]: T[K]['is'] extends new (firstArg: infer P) => ClassA ? { is: T[K]['is'], options: P } : never } }) {} // 现在调用不会报错,每个配置项的类型会自动校验 create({ classes: { testClassA: { is: ClassA, options: { foo: 'bar' } }, testClassB: { is: ClassB, options: { bar: 1 } } } })
效果说明
修改后支持任意继承自ClassA的子类传入配置,TypeScript会自动校验每个配置项的options是否匹配对应类构造函数的第一个入参类型,不符合的话会直接抛出类型错误。
内容的提问来源于stack exchange,提问作者WindBridges
相关产品推荐
相关产品推荐

