我需要创建一个函数,该函数需要扩展另一个特定类(类型,而不是实例)的任何类型的类
Class A{}
foo(b: typeof 'extends A')
Class B extends A{}
Class C {}
foo(B) => working
foo(C) => not working
Run Code Online (Sandbox Code Playgroud)
如何做呢?
我想您可能对什么是类型感到困惑。在 中foo(B),B不是类型;它是一个构造函数值。这种混淆很常见,可能是因为有时类型和值可以具有相同的名称,例如当您声明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
Run Code Online (Sandbox Code Playgroud)
类型的new (...args: any[]) => A意思是“任何生成类型实例的构造函数A”。之所以foo(B)有效,是因为是一个构造函数,B它生成类型( 的子类型)的实例。因此确实会产生实例并起作用。但由于该类型不是 的子类型,因此会产生错误。BABAfoo(B)CAfoo(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
Run Code Online (Sandbox Code Playgroud)
class E {}另请注意,不建议使用空类,即使是示例代码也是如此,因为 TypeScript 类型系统基于结构而不是名称。由于class A {}和class C {}具有相同的(空)结构,如果我保留这些类型,调用foo(C)将不会给出错误。如有疑问,请向编译器希望以不同方式处理的类型添加不同的属性。
好的,希望有帮助;祝你好运!
| 归档时间: |
|
| 查看次数: |
2448 次 |
| 最近记录: |