难以理解的打字稿泛型函数重载

Incomprehensible typescript generic function overload

在学习 TypeScript 时,我注意到一个奇怪的行为。

function concat5<T>(strs: T, strs2: T): T;
function concat5(strs: string, strs2: string) {
    return strs + strs2;
}

concat5(123, 12);
concat5({a:1}, {b:2});

我认为这段代码有误。 但是,IDE.

中没有出现错误

为什么?

TypeScript 与Java/C#不一样,其中Type是运行时的一部分,JavaScript没有运行时类型限制,没有转换错误,没有类型转换错误,都是TypeScript 中的类型只停留在编辑器和编译器中,编译后,所有类型都消失了。而且JavaScript也没有函数重载,因为没有类型,任何类型的对象都可以作为参数传入函数。

在您的情况下,函数重载只是声明,无法根据实现自动检测错误。它只能根据 指定的类型.

检测错误

function concat5<T>(strs: T, strs2: T): T; 只说明 strsstrs2 应该是同一类型,没有限制 T 可以。

以下导致错误,它表示实现与声明不匹配。

function concat5<T>(strs: T, strs2: number): T;
function concat5(strs: string, strs2: string) {
    return strs + strs2;
}

让我们看这个例子,

function concat5<T extends number>(strs: T, strs2: T): T;
function concat5(strs: string, strs2: string) {
    return strs + strs2;
}
function concat5<T1 extends number, T2>(strs: T1, strs2: T2): T1;
function concat5(strs: string, strs2: string) {
    return strs + strs2;
}

The reason this does not give any error is, JavaScript can accept any object for string input as it will eventually convert all objects to string, so it does not give wrong implementation error in this case. As long as both parameters are are not explicitly specified.

为了好玩 如果你打开 Chrome 的控制台并输入 {} + {},你将看到结果 [object Object][object Object]。 JavaScript 允许任意两种类型的连接,它们被转换为字符串。

>{} + 2
< 2
>2 + {}
<"2[object Object]"
>null + 2
<2
>2 + undefined
<NaN
>2 + (function(){ return 3; })
<"2function(){ return 3; }"