【问题标题】:how to declare member variable as extended type in TypeScript?如何在 TypeScript 中将成员变量声明为扩展类型?
【发布时间】:2016-12-23 11:00:15
【问题描述】:

有没有办法将“成员变量”定义为“扩展对象”而不是静态类型(不使用接口)?

类似这样的伪代码:

class Foo {

    bar -> extends Rectangle;
    constructor(barInstance:IRectangle){
       this.bar = barInstance;

       this.bar.getArea(); //<-- is code completed because interface IRectangle

       // no type error
       this.bar.someCustomFunction = function() {
       }
    }

}

而不是

class Foo {
    bar: IRectangle;
    //or
    bar:Rectangle;
}

这样我可以添加未在基类或接口上定义的属性而不会出现类型错误,而且还可以从基类获得代码完成。呵呵,懒惰严格打字?

【问题讨论】:

    标签: javascript class inheritance typescript


    【解决方案1】:

    考虑一个受约束的泛型类型参数。

    interface Base {
      prop: number;
    }
    
    interface Child extends Base {
      thing: string;
    }
    
    class Foo<T extends Base> {
      bar: T
    }
    
    var foo = new Foo<Child>();
    foo.bar.thing; // now permitted by the type checker
    

    【讨论】:

    • 我想这样做而不必显式定义“事物”但动态分配它而不会引发类型错误,而且还可以获得代码提示......有点像 this.bar.thing = () = >{ return true ;} 本质上,输入到
    • 如果你让你的类将泛型类型的实例作为构造函数参数,你可以编写一个对象字面量实例并推断其类型。我不确定是否有一种解决方案可以在实例化后分配新属性并对其进行类型检查。这些类型的模式往往会混淆静态分析。
    • 如果以后真的需要添加其他属性,我会让它们成为命名接口的可选成员。
    【解决方案2】:

    我不完全确定我是否理解你,但如果是这样,那么就像这样:

    interface IRectangle {
        getArea(): void;
    }
    
    class Rectangle implements IRectangle {
        getArea(): void {}
        someCustomFunction(): void {}
    }
    
    class Foo<T extends IRectangle> {
        bar: T;
    
        constructor(barInstance: T){
            this.bar = barInstance;
            this.bar.getArea();
    
            // no type error
            if (this.bar instanceof Rectangle) {
                (this.bar as any as Rectangle).someCustomFunction = function() {}
            }
        }
    }
    

    (code in playground)

    【讨论】:

      【解决方案3】:

      交叉口类型

      interface IRectangle {
          getArea: () => number;
      }
      
      class Foo {
          bar: IRectangle & { [key: string]: any; };
      
          constructor(barInstance:IRectangle){
             this.bar = barInstance;
      
             this.bar.getArea(); //<-- is code completed because interface IRectangle
      
             // no type error
             this.bar.someCustomFunction = function() {
             }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-05-03
        • 2018-05-25
        • 2022-01-02
        • 2021-07-20
        • 2020-05-15
        • 1970-01-01
        • 2023-03-22
        • 2010-10-24
        • 1970-01-01
        相关资源
        最近更新 更多