打字稿中的函数类型已重载

时间:2018-09-01 21:54:23

标签: typescript types overloading

如何在不提供具体函数的情况下创建重载的函数类型? 通过检查重载函数的类型,似乎可以使用接口/对象类型上的多个调用签名:

function a(input: string): string
function a(input: number): number
function a(input: string | number): string | number {
  return input
}

type A = typeof a

type B = {
  (input: string): string
  (input: number): number
}

const b: B = a // Okay!

用联合类型定义相同的想法(无需使烦人的重载情况令人满意),也可行,类型在两个方向上都是兼容的!

type C = ((input: number) => number) & ((input: string) => string)

const c: C = b // Okay!

const a2: A = c // Okay too!

但是我现在如何制作适合这种类型的功能?我是否也必须使用重载?

const x: A = (input: string | number) => input

const y: A = (input: string | number) => {
  if (typeof input === "number") return input
  if (typeof input === "string") return input
  throw "excrement"
}

均失败,并出现以下完全相同的错误:

Type '(input: string | number) => string | number' is not assignable to type '{ (input: string): string; (input: number): number; }'.
  Type 'string | number' is not assignable to type 'string'.
    Type 'number' is not assignable to type 'string'.

最糟糕的是,即使我使用可读性较低的联合类型C

,也会发生这种情况
Type '(input: string | number) => string | number' is not assignable to type 'C'.
  Type '(input: string | number) => string | number' is not assignable to type '(input: number) => number'.
    Type 'string | number' is not assignable to type 'number'.
      Type 'string' is not assignable to type 'number'.

希望我正在做一些明显的错误,并且有一个简单的解决方法。 否则,当我需要传递到某个地方的函数处理具有相应返回类型的多个调用签名时,最好的选择是什么?

2 个答案:

答案 0 :(得分:1)

要定义具有多个呼叫签名的功能,如果您无法编写可分配给所需的所有呼叫签名的单个呼叫签名,则必须使用两种重载方法(为了兼容具有实现签名的调用签名)或类型声明。您什么都不会错过。

答案 1 :(得分:0)

You can solve this using a generic声明:

type Input = string | number

function a<T extends Input>(input: T): T {
  return input
}

type A = typeof a

type B = {
  (input: string): string
  (input: number): number
}

const b: B = a // Okay!

type C = ((input: number) => number) & ((input: string) => string)

const c: C = b // Okay!

const a2: A = c // Okay too!

对于xy,您不能宽松地定义参数类型,并期望严格推断输出类型。如果要将xy声明为A类型,请省略为函数定义输入类型的方法:

const x: A = input => input

const y: A = input => {
  if (typeof input === "number") return input
  if (typeof input === "string") return input
  throw "excr"
}

您可以在TypeScript Playground demo处验证以上所有内容。