简体   繁体   English

如何在打字稿中正确重载具有多个参数的函数?

[英]How to overload a function with multiple parameters correctly in typescript?

I'm trying to define a function includes , that works for both, arrays and strings.我正在尝试定义一个函数includes ,它适用于数组和字符串。

But I'm having trouble typing it correctly.但是我无法正确输入它。 If I understand correctly, overloading is possible using unions.如果我理解正确,则可以使用联合进行重载。 So this is what I'm trying:所以这就是我正在尝试的:

// 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;
}

But I'm getting the error:但我收到错误:

'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype

which makes sense, because if arr is of type T , el shouldn't be of type string , but the unions makes that a "possibility".这是有道理的,因为如果arrT类型,则el不应该是string类型,但联合使它成为“可能性”。

So how would I correctly type the implementation here to say that the arguments may be either T[] and T or string and string ?那么我如何正确输入这里的实现来说明参数可能是T[] and Tstring and string

It's not safe to call arr.indexOf(el) where arr is T | string[]调用arr.indexOf(el)是不安全的,其中arrT | string[] T | string[] and el is T | string T | string[]elT | string T | string because the compiler isn't sure that you're not mismatching them, as in "typescript".indexOf(2) or [1,2,3].indexOf("rip") . T | string因为编译器不确定您是否不匹配它们,如"typescript".indexOf(2)[1,2,3].indexOf("rip") The fact that the type of arr and el should be correlated is hard to express in TypeScript. arrel的类型应该相关这一事实在 TypeScript 中很难表达。 In the absence of correlated record types (see microsoft/TypeScript#30581) ], it's reasonable to do less type-safe things like use any or other workarounds inside the implementation, since the overload call signatures prevent any such unsoundness from being visible to callers of your function.在没有相关记录类型的情况下(参见 microsoft/TypeScript#30581) ],在实现中使用any或其他变通方法等不太安全的事情是合理的,因为重载调用签名可以防止调用者看到任何此类不健全的情况你的功能。

However, in your case, I'd be inclined to use the following implementation signature:但是,在您的情况下,我倾向于使用以下实现签名:

export function includes<T>(arr: { indexOf(x: T): number }, el: T) {
    return arr.indexOf(el) !== -1;
}

Here, all we care about is the fact that arr has an indexOf() method that takes a value of some type T and returns a number , and that el is a T .在这里,我们只关心arr有一个indexOf()方法,它接受某种类型T的值并返回一个number ,而el是一个T This makes arr.indexOf(el) compile with no error no matter what, and it's compatible with both of the overload call signatures.这使得arr.indexOf(el)编译都不会出错,并且它与两个重载调用签名兼容。 In fact, you might even want to ditch the overloads and just use the above definition, unless you have some reason why includes() should be restricted to string -or- Array<T> inputs.事实上,您甚至可能想要放弃重载而只使用上面的定义,除非您有某种理由将 contains includes()限制为string - 或 - Array<T>输入。 Let's make sure it behaves:让我们确保它的行为:

includes("typescript", "rip"); // okay
includes([1, 2, 3], 2); // okay

includes("typescript", 2); // error
includes([1, 2, 3], "rip"); // error

Looks good to me.在我看来很好。 Hope that helps;希望有所帮助; good luck!祝你好运!

Link to code 代码链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM