在TypeScrip中重载函数的诀窍是last function argument declaration.TypeScrip ignores该last声明externally来自该函数,并且仅使用该声明来键入inside函数签名.
最后一个声明需要满足all个重载,您可以在function overloads的打字脚本文档中看到这一点.要做到这一点,最简单的方法是传递所有参数并返回值为any
.
function func(v: number): number
function func(v: string): string
function func(v: any): any {
return v;
}
func(false); // still throws type error - see note with error below
在外部,您可以only使用数字或字符串调用此函数.因此,如果我try 使用false
调用它,它仍然会抛出一个类型错误.因此,这验证了上一个函数声明仅用于内部类型,只要它们满足所有重载.还要注意的是,该错误仅指2
过载not和3
.
func(false);
^^^^^
No overload matches this call.
Overload 1 of 2, '(v: number): boolean', gave the following error.
Argument of type 'boolean' is not assignable to parameter of type 'number'.
Overload 2 of 2, '(v: string): boolean | undefined', gave the following error.
Argument of type 'boolean' is not assignable to parameter of type 'string'.(2769)
但是这种键入any
的方法是不精确的,并且在函数签名中提供了非常松散的类型.一种better的方式是对每个函数重载参数和返回值求值为union.所以在这个简单的例子中它看起来像...
function func(v: number): number
function func(v: string): string
function func(v: number | string): number | string {
return v;
}
func(1) // no error
func('string') // no error
func(false) // throws type error
因此,在您的情况下,您可以简单地使用此代码.
type Type = {
x: string
}
function func<T extends Type>(v: T): boolean
function func<T extends Type>(v: T | null): boolean | undefined
function func<T extends Type>(v: T | null): boolean | undefined {
return true
}
const getValue = (): Type | null => {
return null
}
let x = getValue()
func(x) // no more errors
是的,这是重复第二个重载声明,这不是一个错误,这是必需的!删除此重复声明会使代码错误成为原始代码.请参阅上面讨论的与最后一个函数声明相关的推理.
请参阅工作TS操场演示here
仅供参考-当每个重载声明有多个不同的泛型和/或参数/返回时,满足所有类型会变得更加困难.在这一点上,取消any
的类型(选项1)成为一个明智的 Select .