typescript - typescript 中的重载函数类型

标签 typescript types overloading

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

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'.

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

最佳答案

您可以使用 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 ,您不能松散地定义参数类型并期望严格推断输出类型。如果要声明 x,请省略定义函数的输入类型。和 y作为类型 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 上验证上述所有内容。 .

关于typescript - typescript 中的重载函数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52132459/

相关文章:

c++ - 类型转换 C++ 的行为方式很奇怪

java - 当一个类实现两个接口(interface)时,接口(interface)具有相同的方法名称但不同的返回类型,为什么它不起作用?

c++ - 是否可以使用单个定义同时定义const和常规版本的函数? (使用模板,自动,decltype等)

java - 使用重载和覆盖的方法选择

typescript :意外未知

javascript - Angular Material 对话框 - AGM 贴图

java - 如何从删除中转换通用类型

mysql - tinyint 还是 varchar(1)?

reactjs - 覆盖 MuiContainer 类时如何摆脱 Typescript 类型错误?

javascript - 如何解决 ionic 2 中 self.context.anim is not a function 错误?