【问题标题】: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",所以我想知道是否有任何包含类。

【问题讨论】:

    标签: angular typescript


    【解决方案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

    【讨论】:

    【解决方案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&lt;T&gt; 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&lt;any&gt; | Function | string的签名 是一个抽象签名,允许我们注入以上所有内容。

        【讨论】:

        • 很遗憾,当您尝试classRef : Type&lt;Foo&gt; = (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&lt;T&gt;: (a: T) =&gt; Instance&lt;T&gt;, staticMember: string}构造
        • 完美。这将为静态成员启用类型提示。
        【解决方案6】:

        以下对我有用:

        type ClassRef = new (...args: any[]) => any;
        

        我的用例:

         interface InteractionType { [key: string]: ClassRef; }
        

        【讨论】:

        • 很遗憾,当您尝试classRef : ClassRef&lt;Foo&gt; = (new Foo()).constructor时它失败了
        【解决方案7】:

        这是一个仅包含类的类型示例:

        declare type Class<T = any> = new (...args: any[]) => T;
        

        【讨论】:

          猜你喜欢
          • 2021-03-25
          • 1970-01-01
          • 2014-08-28
          • 2022-12-18
          • 2016-02-02
          • 1970-01-01
          • 2018-06-01
          • 2015-11-18
          • 2018-09-17
          相关资源
          最近更新 更多