如何通过参数泛型值自动推断方法的泛型返回类型?
修复TypeScript泛型类型推断问题
问题出在AnimalFood类的泛型参数A没有被实例结构“固化”——TypeScript无法从当前的AnimalFood实例中保留具体的Dog类型,只能推断到它的上限Animal。
修复方案一:添加类型标记属性
给AnimalFood类加一个可选的类型标记属性,让TypeScript能捕获到具体的泛型类型:
interface Animal { name : string } interface Dog extends Animal { goodBoy : boolean } class AnimalFood<A extends Animal> { // 仅用于类型推断的可选属性,不影响运行时逻辑 readonly _animalType?: A; feed( animal : A ) { // Do something } } class AnimalStore<A extends Animal> { buyFood( animal : A ) { // Do something } } const findFoodStore = <A extends Animal>( food : AnimalFood<A> ) : AnimalStore<A> => { return new AnimalStore<A>(); }; const dogStore = new AnimalFood<Dog>(); const animalFood = findFoodStore( dogStore ); // 现在自动推断为AnimalStore<Dog> const dogFood = findFoodStore<Dog>( dogStore ); // 推断为AnimalStore<Dog> const moreDogFood : AnimalStore<Dog> = findFoodStore( dogStore ); // 推断为AnimalStore<Dog>
修复方案二:使用私有符号属性
如果不想在类中暴露额外属性,可以用私有符号来标记类型,避免影响外部接口:
interface Animal { name : string } interface Dog extends Animal { goodBoy : boolean } // 定义私有符号,仅用于内部类型标记 const typeMarker = Symbol(); class AnimalFood<A extends Animal> { // 私有符号属性,外部无法访问,仅用于固化泛型类型 private [typeMarker]?: A; feed( animal : A ) { // Do something } } class AnimalStore<A extends Animal> { buyFood( animal : A ) { // Do something } } const findFoodStore = <A extends Animal>( food : AnimalFood<A> ) : AnimalStore<A> => { return new AnimalStore<A>(); }; const dogStore = new AnimalFood<Dog>(); const animalFood = findFoodStore( dogStore ); // 自动推断为AnimalStore<Dog>
原理:通过在AnimalFood类中添加与泛型A绑定的属性,TypeScript就能从实例中识别出具体的泛型类型,不再退回到Animal上限,从而让findFoodStore自动推断出正确的返回类型。
内容的提问来源于stack exchange,提问作者Herbert Marshall
相关产品推荐
相关产品推荐

