Typescript - 期望扩展类的类型

tom*_*mes 2 typescript

我需要创建一个函数,该函数需要扩展另一个特定类(类型,而不是实例)的任何类型的类

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)

如何做呢?

jca*_*alz 5

我想您可能对什么是类型感到困惑。在 中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)将不会给出错误。如有疑问,请向编译器希望以不同方式处理的类型添加不同的属性。

好的,希望有帮助;祝你好运!