Typescript String Literal类型在函数重载中不起作用

时间:2016-04-21 21:03:13

标签: typescript overloading

根据TypeScript documentation(查找字符串文字类型部分),以下代码应适用于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.

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

3 个答案:

答案 0 :(得分:1)

您是否尝试使用非专业签名?

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

function createElement(tagName: string): Element { /* ... */ }

```

答案 1 :(得分:0)

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

字符串文字+功能重载方法

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>();

答案 2 :(得分:0)

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

createElement("a"); // Error!

调用时会触发编译器错误:

private void CreateDerivedBindings()
{
    this.Articles = this.ViewModel.Articles.CreateDerivedBindingList(x => x);
    this.ViewModel.Articles.ItemChanged.Subscribe(_ => this.Articles.Reset());
    //this.Articles.ChangeTrackingEnabled = true;
    this.articlesDataGridView.DataSource = this.Articles;
}

private IReactiveDerivedBindingList<ArticleViewModel> Articles { get; set; }

正如您所发现的,您不能只使用函数签名中的文字开始。很烦人,IMO。我希望他们在未来的TS版本中清理它!