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

klh5stk1  于 2022-12-24  发布在  TypeScript
关注(0)|答案(1)|浏览(131)

给定以下代码:

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

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

我得到了错误
类型'(b:编号,a:string)=〉void "不能赋值给类型"{(a:字符串):无效;(b:编号,a:字符串):无效; }'. ts(2322)索引. ts(15,3):所需类型来自此处对类型"Foo"声明的属性"func"
我看到了使用类的答案,但是如何在普通对象上实现呢?

sr4lhrrt

sr4lhrrt1#

编译器显然不满意func(b, a)需要第二个参数,而Foofunc方法不需要,可以通过在实现中使a可选来消除这个错误:

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

注意,通常情况下,并不总是能找到一种可以编译的方法。重载函数 * 语句 * 允许它们的实现比任何调用签名类型化得更松散,但重载函数 * 表达式 * 并不是这样工作的:

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

microsoft/TypeScript#47669中有一个特性请求,允许箭头函数以与函数语句相同的方式重载,但目前它还不是语言的一部分。
因此,如果你发现自己有一个不可能实现的重载arrow函数,你应该重构为一个函数语句:

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

或者使用类型Assert来放松类型检查,使其能够编译:

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

Playground代码链接

相关问题