我试图创建一个函数,它将参数传递给另一个函数。这两个函数需要有相同的重载。
function original (a: number): boolean;
function original (a: string, b: string): boolean;
function original (a: number | string, b?: string): boolean {
return true;
}
function pass (a: number): boolean;
function pass (a: string, b: string): boolean;
function pass (a: number | string, b?: string): boolean {
return original(a, b);
}
这行不通。
类型为"string"的参数|number "不能赋给类型为" string "的参数。
类型"number"不能赋给类型"string"。(2345)input. tsx(4,10):对此实现的调用本应成功,但重载的实现签名对外部不可见。
Playground
5条答案
按热度按时间vddsk6oq1#
你可以使用typeof操作符将你的
pass
函数声明为original
函数的类型,例如。这里是Playground
ogsagwnx2#
添加额外过载:
现在它看起来像:
您不再需要第二个重载
function original(a: string, b: string): boolean
,但仍可以保留它以提高代码的可读性。Playground
6tqwzwtp3#
大多数情况下,函数重载的实现会接收到最松散的类型,“any”或“unknown”。但是“any”会使你丢失类型(所有相关变量都将变为“any”类型),所以“unknown”是唯一的选择。为什么实现会接收到最松散的类型?
你重载函数仅仅是因为你想让函数接受不同类型/数量的参数。但是,你怎么知道函数被调用时传入的参数的类型呢?你不知道,你必须先做一些类型检查。
由于实现函数的类型签名在外部不可见,因此您不会得到
pass(unknown, unknown)
签名,只会建议使用实现函数上面的两个签名。dffbzjpn4#
这里有一个解决方案,它不使用类型Assert,也不更改或添加任何重载签名到任何函数:使用IIFE创建两个函数,其中函数在IIFE的“private”作用域内具有较弱的签名,但在作用域之外具有较强的签名。
试验:
Playground链接
xesrikrc5#
在实现中向任何一个强制转换;)。对于重载签名,您可以确定除了允许的参数之外没有其他内容。
或者使用命名元组而不是重载(效果与重载类似)。