Typescript 中是不是有“类”的类型? “任何”包括它吗?
Posted
技术标签:
【中文标题】Typescript 中是不是有“类”的类型? “任何”包括它吗?【英文标题】:Is there a type for "Class" in Typescript? And does "any" include it?Typescript 中是否有“类”的类型? “任何”包括它吗? 【发布时间】:2017-01-16 11:59:18 【问题描述】:在Java 中,您可以使用“Class”类型将class to a method 作为参数。我在打字稿文档中没有找到任何类似的东西 - 是否可以将一个类交给一个方法?如果是这样,“任何”类型是否包括此类类类型?
背景:我在使用 Webstorm 时遇到问题,告诉我无法在 Angular 2 中将课程移交给 @ViewChild(...)
。但是,Typescript 编译器不会抱怨。 @ViewChild()
的签名似乎是"Type<any> | Function | string"
,所以我想知道是否有任何包含类。
【问题讨论】:
【参考方案1】:您在 typescript 中要求的等价物是 new(): Class
类型,例如:
class A
function create(ctor: new(): A ): A
return new ctor();
let a = create(A); // a is instanceof A
(code in playground)
上面的代码只允许构造函数没有参数的类。如果你想要任何课程,请使用new (...args: any[]) => Class
【讨论】:
注意 new(): Class
也可以写成new () => Class
。 github.com/Microsoft/TypeScript/blob/v2.6.1/doc/spec.md#3.8.9
请注意,您可能需要new (...args: any[]) => Class
。此答案中建议的代码将仅允许其构造函数没有参数的类,这可能不是您所追求的。
新的角度全局类型链接github.com/angular/angular/blob/master/packages/core/src/…
我的类也有静态方法,会这样包含在类型中吗?
这不适用于具有仅公开静态工厂方法的私有构造函数的类(例如LocalDate)【参考方案2】:
是否可以将类交给方法?如果是这样,“任何”类型是否包括此类类类型?
是的,是的。 any
包括所有类型。
这是一个仅包含类的类型示例:
type Class = new(...args: any[]): any; ;
然后使用它:
function myFunction(myClassParam: Class)
class MyClass
myFunction(MyClass); // ok
myFunction(); // error
你不应该在为Function
传递一个类时出错,因为这应该可以正常工作:
var func: Function = MyClass; // ok
【讨论】:
【参考方案3】:Angular 内部 declare Type
为:
export interface Type<T> extends Function new (...args: any[]): T;
使用 TypeScript3 应该可以在不重载函数的情况下添加 types for arguments:
export interface TypeWithArgs<T, A extends any[]> extends Function new(...args: A): T;
例子:
class A
function create(ctor: Type<A>): A
return new ctor();
let a = create(A);
【讨论】:
【参考方案4】:Type<T>
from @angular/core
是 Class 的合适接口。
export interface Type<T> extends Function
new (...args: any[]): T;
您可以使用它来保持对类的引用,而不是此类的实例:
private classRef: Type<MyCustomClass>;
或
private classRef: Type<any>;
根据您对@ViewChild
的问题背景:
@ViewChild 允许注入"string selector"
/ Component
/ Directive
Type<any> | Function | string
的签名
是一个抽象签名,允许我们注入以上所有内容。
【讨论】:
很遗憾,当您尝试classRef : Type<Foo> = (new Foo()).constructor
时它失败了
@l00k 构造函数是一个函数,不幸的是 typescript 不知道您可以在 JS 函数上使用 new
运算符创建新实例。打字稿需要类
这只意味着构造函数属性输入错误。因为运行时类及其构造函数是相同的A === A.prototype.constructor
和(new A()).constructor === A
【参考方案5】:
最简单的解决方案是let variable: typeof Class
。
这里是一个例子:
class A
public static attribute = "ABC";
function f(Param: typeof A)
Param.attribute;
new Param();
f(A);
【讨论】:
这是正确答案。当你想访问静态属性时,使用函数调用语法会失败,否则 一旦您开始在类之间进行继承并且您的类具有不同的构造函数签名,这种方法就会失效。 (想想class B extends A
的构造函数比A
的构造函数接受更多参数。)在这种情况下,编译器不会接受f(B)
。
@Louis 确实,这被认为是一种使用静态成员构建可构造的快速方法。继承类类型必须通过new<T>: (a: T) => Instance<T>, staticMember: string
构造
完美。这将为静态成员启用类型提示。【参考方案6】:
以下对我有用:
type ClassRef = new (...args: any[]) => any;
我的用例:
interface InteractionType [key: string]: ClassRef;
【讨论】:
很遗憾,当您尝试classRef : ClassRef<Foo> = (new Foo()).constructor
时它失败了【参考方案7】:
这是一个仅包含类的类型示例:
declare type Class<T = any> = new (...args: any[]) => T;
【讨论】:
以上是关于Typescript 中是不是有“类”的类型? “任何”包括它吗?的主要内容,如果未能解决你的问题,请参考以下文章
Typescript with Angular HttpClient ErrorType ...在调用类方法时不是函数
TypeScript 中是不是有一种编译时方法来声明一个 keyof 类型,只有映射到特定类型的键? [复制]