打字稿字符串文字类型在函数重载中不起作用

Typescript String Literal Types not working in function overloading

根据 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.

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

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

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

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

```

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

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

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

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

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

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

createElement("a"); // Error!

您不能像您发现的那样只使用函数签名中的文字开始这样做。烦人,国际海事组织。我希望他们在未来的 TS 版本中解决这个问题!