简体   繁体   English

如何在普通对象上实现 TypeScript 中的方法重载?

[英]How to implement method overload in TypeScript on a plain object?

Given this code:鉴于此代码:

type Foo = {
  func(a:string):void;
  func(b:number, a:string):void;
}

const f:Foo = {
  func(b, a) {
    // ???
  }
}

I get the error我得到错误

Type '(b: number, a: string) => void' is not assignable to type '{ (a: string): void;类型 '(b: number, a: string) => void' 不可分配给类型 '{ (a: string): void; (b: number, a: string): void; (b: 数字, a: 字符串): void; }'.ts(2322) index.ts(15, 3): The expected type comes from property 'func' which is declared here on type 'Foo' }'.ts(2322) index.ts(15, 3): 预期类型来自属性'func',它在此处声明为类型'Foo'

I see answers using classes, but how to implement on plain objects?我看到使用类的答案,但如何在普通对象上实现?

The compiler is apparently unhappy that func(b, a) requires a second argument while the func method of Foo does not.编译器显然不高兴func(b, a)需要第二个参数,而Foofunc方法不需要。 You can get rid of the error by making a optional in the implementation:您可以通过在实现中a 可选来消除错误:

const f: Foo = {
  func(b, a?) {    
  //       ^-- optional
  }
}

Note that in general it's not always possible to find a way to do this that will compile.请注意,通常并不总能找到一种可以编译的方法。 Overloaded function statements allow their implementation to be more loosely typed than any of the call signatures, but overloaded function expressions don't work that way: 重载函数语句允许它们的实现比任何调用签名更松散,但重载函数表达式不能那样工作:

function barFunc(a: string): number;
function barFunc(b: number, a: string): string;
function barFunc(b: string | number, a?: string) {
  return typeof b === "string" ? b.length : a // okay
}

type Bar = {
  func(a: string): number;
  func(b: number, a: string): string;
}
const g: Bar = {
  func(b, a?) { // error!
    return typeof b === "string" ? b.length : a
  }
}

There's a feature request at microsoft/TypeScript#47669 to allow for arrow functions to be overloaded the same way that function statements are, but for now it's not part of the language.microsoft/TypeScript#47669有一个功能请求允许箭头函数以与函数语句相同的方式重载,但现在它不是语言的一部分。

So if you do find yourself with an impossible-to-implement overloaded arrow function, you should either refactor to a function statement:所以如果你确实发现自己有一个不可能实现的重载箭头函数,你应该重构为一个函数语句:

const h: Bar = { func: barFunc }; // okay

Or use type assertions to loosen the type checking enough to get it to compile:或者使用类型断言来放松类型检查以使其能够编译:

const i: Bar = {
  func(b, a?) { 
    return (typeof b === "string" ? b.length : a) as any // okay
  }
}

Playground link to code 游乐场代码链接

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

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