【问题标题】:Unable to Extend Class from Dictionary of Classes无法从类词典中扩展类
【发布时间】:2018-06-10 06:47:01
【问题描述】:

问题:

我试图从一个高阶类方法返回一个类声明,该类方法从类映射{"SOME_CLASS" : SomeClass} 扩展一个类,关键是高阶类方法的参数。但是 Typescript 抛出此错误...
注意:我没有使用任何外部库。

错误:

不能将“new”与类型缺少调用或构造签名的表达式一起使用。

尝试:

我试图将类类型强制转换为“Newable”,但是我丢失了正在扩展的类的类型绑定。

片段

/// Contrived Example
interface BaseConfig {
  options: {
    profileHref: string
  }
}
abstract class Base { /*< BaseClass Implementations >*/
}
/// Example Class 1
class ProfileIcon extends Base {
  constructor(config: {
    options: {
      profileHref: string
    }
  }) {
    super(config);
  }
}
/// Example Class 2
class ScriptBlock extends Base {
  constructor(config: {
    options: {
      src: string
    }
  }) {
    super(config);
  }
}
}

class Manager {
  protected STORE: RootStore;
  constructor() {}
  public dispatchNewElement(elementType: keyof typeof ELEMENT_MANIFEST) {
    const storeShard = this.STORE.shard();
    const elementClass = ELEMENT_MANIFEST[elementType];


    /*
    //// ERROR: type 'typeof ProfileIcon | typeof ScriptBlock' is not a constructor function type.
    /// NOTE: 
    >> const T = new elementClass(...args)
    >> throws - Cannot use 'new' with an expression whose type lacks a call or construct signature.
    ////
    ////
    */

    return class extends /*err*/ elementClass /*endErr*/ {
      protected STORE_SHARD: typeof RootStore;
      constructor(elementConfig: { < unique fields to class implementation >
      }) {
        super(elementConfig);
        this.STORE_SHARD = storeShard;
      }
    }
  }

  /// Element Class Dictionary
  const ELEMENT_MANIFEST = {
    "PROFILE_ICON": ProfileIcon,
    "SCRIPT_BLOCK": ScriptBlock
  }

请原谅任何格式错误,这可能是我关于堆栈溢出的第二篇文章。干杯!

来自评论的更新

类返回类扩展另一个类的示例

class Master {
    public STATE: any;
    constructor() {
        this.STATE = { name: "foo" };
    }
    public dispatchNewClass(classType: string) {
        const myRefImage = Img;
        ////
        /* Works as a refVariable however..
        if i declare like...
            const myRefImage: Icon | Img
        I will get  
        >> Type 'typeof Img' is not assignable to type 'Icon | Img'.  
        >> Type 'typeof Img' is not assignable to type 'Img'.  
        >>Property 'TagName' is missing in type 'typeof Img'.
        */
        ///
        const asObject {}
        const ROOT = this.STATE;
        return class Slave extends myRefImage {
            protected ROOT: typeof ROOT;
            constructor(tagName: string) {
                super(tagName as "img")
                this.ROOT = ROOT;
            }
        }
    }
}

【问题讨论】:

    标签: typescript types casting extending-classes


    【解决方案1】:

    这在 TypeScript 中不起作用。

    TypeScript 中的类型系统只存在于编译时。

    当代码被编译时,它是纯 JavaScript。

    您不能定义新类和/或从另一个仅在运行时知道的类扩展它。

    【讨论】:

    • 感谢您的输入,但我认为这不是 100% 的情况,当我直接扩展类名或从引用变量扩展类名时,我能够做到这一点。但是我不能动态设置它动态扩展的类。是否有可能适合此的泛型类型?干杯!
    • 您能否发布一个示例,说明“直接扩展类名或从引用变量扩展类名”的含义?
    • 我已更新帖子以包含此示例。似乎问题出在由const extendClass : ClassA | ClassB = ClassA; 形成的联合类型中,理论上我可以做一个大开关/if else,它会根据传递的“className”返回每个可能的实例,但我只会考虑如果没有其他的可能性。干杯
    • 在您的示例中,它之所以有效,是因为 myRefImage 可以静态分析为 Img 类。这就是它起作用的原因。在您的原始问题中,它是动态确定的,因此这是不可能的。
    • 啊,有道理。有没有办法欺骗类型系统来解决这个问题?我想我将创建一个全局 ClassFactory 函数,其中包括返回每种类型的新扩展类的函数(这样我可以使用静态类名)——除非有明显更好的选择。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-14
    • 2014-06-19
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多