我需要创建一个函数,该函数期望任何类型的类都可以扩展另一个特定的类(类型,而不是实例)
Class A{}
foo(b: typeof 'extends A')
Class B extends A{}
Class C {}
foo(B) => working
foo(C) => not working
怎么办?
答案 0 :(得分:2)
我想您可能对什么类型感到困惑。在foo(B)
中,B
不是类型;它是一个构造函数值。这种混淆非常普遍,可能是因为sometimes types and values can have the same name,例如当您声明class
时。
无论如何,如果您的要求是foo()
应该接受A
实例的构造函数中的任何内容,则应执行以下操作:
class A { a: string = "A" }
declare function foo(ctor: new (...args: any[]) => A): void;
class B extends A { b: string = "B" }
class C { c: string = "C" }
foo(A); // okay
foo(B); // okay
foo(C); // error
类型new (...args: any[]) => A
的意思是“任何产生类型A
的实例的构造函数”。因此foo(B)
之所以有效,是因为B
是一个构造器,它生成类型为B
(A
的{{3}})的实例。因此B
确实产生了A
实例,并且foo(B)
起作用了。但是由于类型C
不是A
的子类型,因此foo(C)
会产生错误。
我不知道您想在foo()
的实现中做什么。如果要实际使用传入的构造函数,则可能应该考虑构造函数的参数是什么,并限制foo()
仅接受支持这些参数的构造函数。例如,如果您期望foo()
不带任何参数调用其构造函数,则可能应该限制它:
class A { a: string = "A" }
class B extends A { b: string = "B" }
class C { c: string = "C" }
// D's constructor requires a string argument
class D extends A { constructor(private d: string) { super(); } }
// ctor must be a no-arg constructor
declare function foo(ctor: new () => A): void;
foo(A); // still okay
foo(B); // still okay
foo(C); // still error
foo(D); // error
还要注意,具有subtype之类的空类是not recommended,即使是示例代码也是如此,因为TypeScript类型系统基于structures而不是names。由于class E {}
和class A {}
具有相同的(空)结构,因此如果我保留这些类型,则调用class C {}
不会出错。如有疑问,请为打算由编译器区别对待的类型添加不同的属性。
好的,希望能有所帮助;祝你好运!