基于类中属性值推导对象属性类型的TypeScript问题
TypeScript类中联合类型的类型推导问题
TL;DR:TypeScript在类中使用联合类型时,无法自动推导具体的子类型成员
我在使用TypeScript处理类与联合类型时遇到了问题。以下是定义的基础类型:
type CommonData = { name: string } type Dog = { age: number } & CommonData type Bat = { wingspan: number } & CommonData type Animal = { type: "dog" data: Dog } | { type: "bat" data: Bat }
Animal类型是一个联合类型,会根据type字段的值确定data的具体类型。直接使用Animal类型创建对象时,TypeScript能正确根据type推导data的类型:
const bat: Animal = { type: "bat", data: { name: "tim", wingspan: 9000 } } // 此处TypeScript能正确识别bat.data为Bat类型,支持类型推导 bat.data.name
但将该类型应用到类中时,TypeScript无法识别data的具体类型:
class AnimalClass { animal: Animal constructor(animal: Animal) { this.animal = animal } } const dog = new AnimalClass({ type: "dog", data: { name: "bob", age: 10 } }) // 此处TypeScript将dog.animal.data识别为Dog | Bat,无法推导具体为Dog类型 dog.animal.data
请问是否可以修改代码,让TypeScript推导出dog.animal.data的类型为Dog?
解决方案
将AnimalClass定义为泛型类,让泛型约束为Animal的子类型,这样TypeScript就能在实例化时捕获具体的类型信息:
class AnimalClass<T extends Animal> { animal: T constructor(animal: T) { this.animal = animal } } const dog = new AnimalClass({ type: "dog", data: { name: "bob", age: 10 } }) // 现在TypeScript能正确推导dog.animal.data为Dog类型 dog.animal.data.age // 类型检查正常通过
这种方式的核心是,泛型T会保存传入的具体Animal子类型(而非整个联合类型),从而保留type与data之间的类型关联,让TypeScript能够进行精准的类型推导。
内容的提问来源于stack exchange,提问作者Tyler Wilson
相关产品推荐
相关产品推荐

