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

Posted

技术标签:

【中文标题】难以理解的打字稿泛型函数重载【英文标题】:Incomprehensible typescript generic function overload 【发布时间】:2020-06-30 10:53:43 【问题描述】:

在学习 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 中不会出现错误。

为什么?

【问题讨论】:

他们说函数重载不是类型安全的。多么好的收获!看起来像一个整体 @MaciejSikora 公共签名和实现签名通常被松散地检查。就像类型断言一样,编译器的一个元素会说“好吧,如果你这么说” 是的,谢谢提香 【参考方案1】:

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

在您的情况下,函数重载只是声明,不能根据实现自动检测错误。它只能根据Types Specified检测错误。

function concat5&lt;T&gt;(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;

这没有给出任何错误的原因是,JavaScript 可以接受任何对象作为字符串输入,因为它最终会将所有对象转换为字符串,因此在这种情况下它不会给出错误的实现错误。只要两个参数都没有明确指定。

为了好玩 如果你打开 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; "

【讨论】:

以上是关于难以理解的打字稿泛型函数重载的主要内容,如果未能解决你的问题,请参考以下文章

带有约束的打字稿泛型不能分配给泛型接口

打字稿泛型返回类型

打字稿泛型-“扩展对象”毫无意义吗?最佳做法是啥?

打字稿泛型类型 T toString

typescript 打字稿泛型示例

typescript 打字稿泛型