TypeScript 泛型:'类型不可分配给类型 T'
Posted
技术标签:
【中文标题】TypeScript 泛型:\'类型不可分配给类型 T\'【英文标题】:TypeScript Generics: 'type is not assignable to type T'TypeScript 泛型:'类型不可分配给类型 T' 【发布时间】:2018-09-19 20:08:09 【问题描述】:我已经创建了一个工厂,它将创建某些类的实例。我想使用泛型来确保返回的所有对象都来自扩展抽象类的子类。
我认为下面显示的createInstance
方法的逻辑可以描述为'createInstance() 将返回一个类型T
,该类型被限制为扩展Animal 的类。
如您所见,Lion 扩展了 Animal,但我仍然收到编译器警告 type Lion is not assignable to type T
。
abstract class Animal
abstract makeSound(): void;
class Bear extends Animal
public makeSound()
console.log('growl');
class Lion extends Animal
public makeSound()
console.log('roar');
function createInstance<T extends Animal>(type: string): T
switch(type)
case 'bear':
return new Bear(); // 'type Bear is not assignable to type T'
case 'lion':
return new Lion(); // 'type Lion is not assignable to type T'
createInstance().makeSound();
我在TypeScript Generics 文档的末尾读到:
在 TypeScript 中使用泛型创建工厂时,有必要 通过构造函数引用类类型。例如,
function create<T>(c: new(): T; ): T return new c();
但如果可能的话,我真的不想将类构造函数传递给函数,并且想了解为什么我首先会收到 not assignable to type T
消息。
谢谢
【问题讨论】:
【参考方案1】:如果你的函数总是返回一个Lion
它的结果类型不是真正的通用。例如,您可以编写 create<Tiger>()
,而您的函数仍将返回 Lion
。真正的泛型函数会返回一个遵循泛型参数的值。
正如你所发现的,你可以将构造函数作为参数传递:
function create<T>(c: new(): T; ): T
return new c();
或者你可以让你的函数不是通用的,并让它返回一个Animal
或Lion
。如果您有基于确定返回类型的参数值的逻辑,则可以有更多的重载:
// Public signatures, we tie function parameter values to return value for specific types
function createInstance(type: "Lion"): Lion
function createInstance(type: "Tiger"): Tiger
// Private signature, not visible from outside
function createInstance(type: "Lion" | "Tiger"): Animal
if(type === "Lion")
return new Lion();
else if(type === "Tiger")
return new Tiger();
let tiger = createInstance("Tiger"); // will be typed as Tiger
let lion = createInstance("Lion");// will be typed as Lion
let err = createInstance("Lama");// will be an error since the function does not know how to create a Lama
【讨论】:
感谢您的回复。对我来说是个坏例子。我的意思是可以根据开关选择返回的类。让我换个例子。A true generic function would return a value that honors the generic parameter
。所以现在我已经更改了我的示例并且在createInstance()
方法中有两个选项,我的类是否不是通用的,因为它总是需要返回一个扩展动物的类?我不希望它简单地返回一个 Animal,因为我可能想使用其他子类特定的方法和属性。相反,我只想知道返回的值 is 是一个 Animal,这样我就可以确定它有一个 makeSound()
方法,但我想要那个实际的子类实例。
@Joe 它仍然不是通用的,因为它不适用于任何T
,仅适用于从Animal
派生的有限数量的类。您应该考虑重载选项,它正是您要寻找的,它根据参数值返回特定类型的动物。
谢谢提香。这很有帮助以上是关于TypeScript 泛型:'类型不可分配给类型 T'的主要内容,如果未能解决你的问题,请参考以下文章
类型“字符串”不可分配给类型“WebkitAppearance |在 React + TypeScript 中未定义?
TypeScript 2.4.1 -> fontWeight -> 类型 'number' 不可分配给类型 '"inherit" | 400 |
react-router-dom TypeScript TS2322:类型'typeof Index'不可分配给类型
Mongoose TypeScript ObjectId 转换 - 类型“字符串”不可分配给类型“条件<ObjectId |未定义>'
Mongoose TypeScript ObjectId 转换 - 类型“字符串”不可分配给类型“条件<ObjectId |未定义>'