【问题标题】:Typescript String Literal Types not working in function overloadingTypescript字符串文字类型在函数重载中不起作用
【发布时间】:2016-04-21 21:03:12
【问题描述】:

根据 TypeScript documentation(查找 String Literal Types 部分),以下代码应该适用于 TypeScript:

function createElement(tagName: "img"): HTMLImageElement;
function createElement(tagName: "input"): HTMLInputElement;
// ... more overloads ...

function createElement(tagName: string): Element {
    // ... code goes here ...
}

当我在 TypeScript Playground 或 Visual Studio 上运行代码或更有意义的变体时,我收到以下错误:

Specialized overload signature is not assignable to any non-specialized signature.

有什么建议吗?在尝试在我自己的代码上实现非常相似的东西后,我遇到了这个错误。

【问题讨论】:

    标签: typescript overloading


    【解决方案1】:

    您是否尝试从非专业签名开始?

    function createElement(tagName: string): Element;
    function createElement(tagName: "img"): HTMLImageElement;
    function createElement(tagName: "input"): HTMLInputElement;
    // ... more overloads ...
    
    function createElement(tagName: string): Element { /* ... */ }
    

    ```

    【讨论】:

    • 它有效,谢谢!伟大的!你有什么解释为什么它有效吗?我正在努力理解。
    • 不确定,可能是因为专门的签名看不到它们之后的实现?更多详情here.
    【解决方案2】:

    回答我自己的问题: 恕我直言,使用泛型可以更好地解决此类问题。

    字符串文字+函数重载方法

    function createElement(tagName: string): Element;
    function createElement(tagName: "img"): HTMLImageElement;
    function createElement(tagName: "input"): HTMLInputElement;
    // ... more overloads ...
    
    function createElement(tagName: string): Element { /* ... */ }
    
    var inputElement = createElement("input");
    

    泛型方法

    function createElement<elementType>(): elementType { /* ... */ }
    
    var inputElement = createElement<HTMLInputElement>();
    

    具有更强类型约束的泛型方法

    function createElement<elementType extends HTMLElement>(): elementType { /* ... */ }
    
    var inputElement = createElement<HTMLInputElement>();
    

    【讨论】:

      【解决方案3】:

      如果您想限制 指定的字符串(例如,当其他情况是错误时),您显然必须首先为类型设置别名。

      type ValidTagOptions = "img" | "input";
      function createElement(tagName: ValidTagOptions): HTMLImageElement;
      function createElement(tagName: ValidTagOptions): HTMLInputElement;
      

      这是在调用时触发编译器错误:

      createElement("a"); // Error!
      

      正如您所发现的,您不能只使用函数签名中的文字开始执行此操作。烦人,海事组织。我希望他们在未来的 TS 版本中清理它!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-13
        • 1970-01-01
        • 2017-03-31
        • 1970-01-01
        • 2019-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多