【问题标题】:Wrapping overloaded functions in Typescript在 Typescript 中包装重载函数
【发布时间】:2022-11-04 06:55:26
【问题描述】:

我在弄清楚如何根据 Typescript 中的条目参数正确包装可能具有多种返回类型的函数时遇到了一些问题。

假设我想要一个函数,当给定VariantEnum .a 作为参数时,将返回ReturnA,而当给定VariantEnum.b 时,将返回ReturnB

鉴于sampleFunction 的以下实现:

enum VariantEnum { a, b }

type ReturnA = string
type ReturnB = number

type VariantReturnMap<V> = 
  V extends VariantEnum.a ? ReturnA :
  V extends VariantEnum.b ? ReturnB : 
  undefined

declare function sampleFunction<V extends VariantEnum>(variant: V): VariantReturnMap<V>

直接调用函数时有效:

sampleFunction(VariantEnum.a) // return type is ReturnA, as expected

但不是在使用包装器调用它时,除非我再次重新声明所有内容:

function wrapperFunction(variant: VariantEnum) {
  // something else

  return sampleFunction(variant) // return type is `(ReturnA | ReturnB)`, since we don't know which variant we have yet
}

wrapperFunction(VariantEnum.a) // return type is still `(ReturnA | ReturnB)`

sampleFunction(VariantEnum.a) // return type is still ReturnA, as expected

据我所知,TS 应该有足够的信息来推断给定包装器返回原始函数,它应该具有相同的返回类型。但是,它总是返回联合类型。

有没有其他方法可以让它推断出正确的类型,而不必再次声明它?

(同样的问题在用不同的方法重载函数时仍然会发生,例如ReturnAReturnB的单独声明)

【问题讨论】:

  • 枚举定义不使用=,它只是enum X { ... }
  • 修复上述俏皮话,在this 操场上,我得到string | number 而不是string。此外,我得到另一个类型错误,您在包装器中调用示例函数。我无法重现您所拥有的,因此我无法准确回答这个问题。
  • this 是你的意思吗?如果是这样,请edit问题中的示例并更正它们。
  • 谢谢@caTS,这正是我的意思;抱歉,我试图从我的代码库中尽可能多地抽象代码,结果出现了一些错误。只是对其进行了编辑,使其看起来像游乐场。还删除了undefined,因为它对我的具体实现并不重要。

标签: typescript


【解决方案1】:

包装器必须具有相同的签名:

function wrapperFunction<V extends VariantEnum>(variant?: V) {
  return sampleFunction(variant);
}

就 TS 而言,包装器中的variantVariantEnum 类型,即使您专门给它VariantEnum.a

Playground

【讨论】:

    猜你喜欢
    • 2020-06-08
    • 1970-01-01
    • 2012-10-24
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多