如何在打字稿中正确重载具有多个参数的函数?
How to overload a function with multiple parameters correctly in typescript?
我正在尝试定义一个适用于数组和字符串的函数 includes
。
但我无法正确输入它。如果我理解正确,可以使用联合重载。所以这就是我正在尝试的:
// Declarations
export function includes<T>(arr: T[], el: T): boolean;
export function includes(str: string, substr: string): boolean;
// Implementation
export function includes<T>(arr: T[] | string, el: T | string) {
return arr.indexOf(el) !== -1;
}
但我收到错误消息:
'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype
这是有道理的,因为如果 arr
是 T
类型,el
不应该是 string
类型,但是联合使得 "possibility".
那么我如何在此处正确键入实现以说明参数可能是 T[] and T
或 string and string
?
调用 arr.indexOf(el)
是不安全的,其中 arr
是 T | string[]
并且 el
是 T | string
因为编译器不确定你是不匹配它们,如 "typescript".indexOf(2)
或 [1,2,3].indexOf("rip")
。 arr
和 el
的类型应该 correlated 这一事实很难在 TypeScript 中表达。在没有 correlated record types (see microsoft/TypeScript#30581)] 的情况下,在实现中使用 any
或其他变通方法等类型安全性较低的事情是合理的,因为重载调用签名可以防止任何此类不健全对您的调用者可见功能。
但是,对于您的情况,我倾向于使用以下实现签名:
export function includes<T>(arr: { indexOf(x: T): number }, el: T) {
return arr.indexOf(el) !== -1;
}
在这里,我们只关心 arr
有一个 indexOf()
方法,它接受某种类型的值 T
和 returns a number
,而 el
是 T
。这使得 arr.indexOf(el)
无论如何都可以毫无错误地编译,并且它与两个重载调用签名兼容。事实上,您甚至可能想要放弃重载并只使用上面的定义,除非您有某种理由将 includes()
限制为 string
-or-Array<T>
输入。让我们确保它的行为:
includes("typescript", "rip"); // okay
includes([1, 2, 3], 2); // okay
includes("typescript", 2); // error
includes([1, 2, 3], "rip"); // error
我觉得不错。希望有所帮助;祝你好运!
我正在尝试定义一个适用于数组和字符串的函数 includes
。
但我无法正确输入它。如果我理解正确,可以使用联合重载。所以这就是我正在尝试的:
// Declarations
export function includes<T>(arr: T[], el: T): boolean;
export function includes(str: string, substr: string): boolean;
// Implementation
export function includes<T>(arr: T[] | string, el: T | string) {
return arr.indexOf(el) !== -1;
}
但我收到错误消息:
'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype
这是有道理的,因为如果 arr
是 T
类型,el
不应该是 string
类型,但是联合使得 "possibility".
那么我如何在此处正确键入实现以说明参数可能是 T[] and T
或 string and string
?
调用 arr.indexOf(el)
是不安全的,其中 arr
是 T | string[]
并且 el
是 T | string
因为编译器不确定你是不匹配它们,如 "typescript".indexOf(2)
或 [1,2,3].indexOf("rip")
。 arr
和 el
的类型应该 correlated 这一事实很难在 TypeScript 中表达。在没有 correlated record types (see microsoft/TypeScript#30581)] 的情况下,在实现中使用 any
或其他变通方法等类型安全性较低的事情是合理的,因为重载调用签名可以防止任何此类不健全对您的调用者可见功能。
但是,对于您的情况,我倾向于使用以下实现签名:
export function includes<T>(arr: { indexOf(x: T): number }, el: T) {
return arr.indexOf(el) !== -1;
}
在这里,我们只关心 arr
有一个 indexOf()
方法,它接受某种类型的值 T
和 returns a number
,而 el
是 T
。这使得 arr.indexOf(el)
无论如何都可以毫无错误地编译,并且它与两个重载调用签名兼容。事实上,您甚至可能想要放弃重载并只使用上面的定义,除非您有某种理由将 includes()
限制为 string
-or-Array<T>
输入。让我们确保它的行为:
includes("typescript", "rip"); // okay
includes([1, 2, 3], 2); // okay
includes("typescript", 2); // error
includes([1, 2, 3], "rip"); // error
我觉得不错。希望有所帮助;祝你好运!