TypeScript 函数重载不一致
Posted
技术标签:
【中文标题】TypeScript 函数重载不一致【英文标题】:Inconsistency in TypeScript function overload 【发布时间】:2021-11-20 16:01:42 【问题描述】:考虑这个例子:
export function fn(arg: string): void;
export function fn(arg: number): void;
export function fn(arg: any)
console.log(arg);
所以,fn
可以用字符串或数字来调用。
fn('hello!');
fn(42);
到目前为止,一切都很好。
但随后fn
在不同的地方执行:
function fn2(arg2: string | number)
fn(arg2);
在这种情况下,TypeScript 会抱怨:
没有重载匹配这个调用。重载 1 of 2, '(arg: string): void',出现以下错误。
Argument of type 'string | number' is not assignable to parameter of type 'string'. Type 'number' is not assignable to type 'string'. Overload 2 of 2, '(arg: number): void', gave the following error. Argument of type 'string | number' is not assignable to parameter of type 'number'. Type 'string' is not assignable to type 'number'.ts(2769)
index.tsx(3, 17): 调用会成功 实现,但重载的实现签名不是 外部可见。
有人可以帮我理解这里发生了什么吗?
【问题讨论】:
【参考方案1】:您可以添加另一个重载
export function fn(arg: string): void;
export function fn(arg: number): void;
export function fn(arg: any): void;
export function fn(arg: any)
console.log(arg);
fn('hello!');
fn(42);
function fn2(arg2: string | number)
fn(arg2);
Playground
【讨论】:
这为我解决了这个问题,但我不知道为什么。你能解释一下为什么这会为我解决这个问题吗? @ElliotLabsLLC 因为新的重载签名接受任何类型的参数。 所以新的arg:any
参数反映了非重载函数参数,这些参数不计入 Transpiler 函数参数构造?
它只涵盖any
thing,包括联合类型,在这种情况下为arg2: string | number
因为没有为联合声明重载并且就打字稿而言,number
或 string
可以分配给 number | string
,但反之则不行【参考方案2】:
重载与联合类型不同。重载定义了“单独的”函数,而联合则允许您将不同的类型作为参数。
// fails
function fn2(arg2: string | number)
fn(arg2); // uses the union type
// works
function fn3(arg2: string | number)
if(typeof arg2 === 'string')
return fn(arg2); // uses string
return fn(arg2); // uses number
这意味着fn2
搜索具有string|number
类型参数的函数声明,而fn3
搜索具有string
类型的函数或具有number
类型作为其第一个参数的函数。
如果您确切知道要作为函数参数的类型,则不应使用any
。
请参阅 documentation 了解联合类型
【讨论】:
以上是关于TypeScript 函数重载不一致的主要内容,如果未能解决你的问题,请参考以下文章