typescript - 如何在 typescript 中为通用参数添加 "newable"约束?

标签 typescript generics type-constraints

我已经知道如何为函数参数添加“可更新”(即具有构造函数)约束(例如下面的 foo 函数的参数),但相同的技术不适用于泛型类型参数。

为什么会这样,如何解决?

enter image description here

type NoParameterCtor<T> = { new(): T }

function foo<T>(ctor: NoParameterCtor<T>) { }

interface Bar<T extends NoParameterCtor<T>> { }

class Zoo { }

foo(Zoo) 
// no compiler error

class Zar implements Bar<Zoo> { }
// Type 'Zoo' does not satisfy the constraint 'NoParameterCtor<Zoo>'

最佳答案

如评论中所述,T extends NoParameterCtor<T>是一个不寻常的约束,意思是“T 是一个创建自身新实例的构造函数”。除非你试图描述 self 复制的构造函数,否则这不是你的意思。

如果你只想T做“任何新事物”,那么您就不需要关心实例类型。假设您使用的是 TS3.0 或更高版本,您可以使用 unknown表示任何类型,尽管您也可以使用 any .所以也许你想要 Bar成为

interface Bar<T extends NoParameterCtor<unknown>> { }

但以下仍然无效:

class Zar implements Bar<Zoo> { } // error! 
// Zoo does not satisfy the constraint NoParameterCtor<unknown>

那是因为类型 Zoo不可更新;它是 Zoo 的实例类型类(class)。我不知道你是否对the difference between named values and named types感到困惑在 TypeScript 中,但如果是这样的话,你就是一个很好的伙伴。简而言之,class Zoo {}引入了一个名为 Zoo类型 ,这是该类的实例类型,以及一个名为 Zoo ,这是此类实例的构造函数。和 Zoo 的类型值不是 Zoo类型。引用 Zoo 的类型构造函数值,需要使用typeof Foo相反:

class Zar implements Bar<typeof Zoo> { } // okay

此外,我假设您已经删除了 Bar 的内容, ZarZoo因为它们在这里不相关。但需要明确的是,空接口(interface)几乎可以匹配所有内容,因为 TypeScript 使用 structural typing .如果Bar需要访问 T 的实例类型, 然后你可以使用内置库类型别名 InstanceType<> 得到它:

interface Bar<T extends NoParameterCtor<unknown>> {
   theConstructor: T,
   theInstance: InstanceType<T>
}

class Zar implements Bar<typeof Zoo> { 
  theConstructor = Zoo; // the constructor
  theInstance = new Zoo(); // an instance
}

希望对您有所帮助。祝你好运!

关于typescript - 如何在 typescript 中为通用参数添加 "newable"约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52727723/

相关文章:

javascript 回调在不可能的调用中被调用两次

angular - 向 Angular router.navigate 添加参数

delphi - 如何更新 TList<T> 中的数据?

f# - 如何正确覆盖受约束的方法

javascript - Object.estimated(类似 Date 对象)未处理为 Date() 类型

javascript - 在 React typescript 中的 useState 钩子(Hook)中使用 PrevState

c# - 需要调用 InsertBulk<T>(IEnumerable<T> pocos) 但 T 仅在运行时知道

java - 使用泛型时未经检查的调用

c# - 什么时候在 C# 中拥有公共(public)无参数构造函数很重要?

c# - 为什么在没有 new() 泛型类型约束的情况下允许 Activator.CreateInstance<T>() ?