【问题标题】:How to define generic function with one concrete type and one inferred type如何用一种具体类型和一种推断类型定义泛型函数
【发布时间】:2019-12-06 04:35:16
【问题描述】:

我有一个泛型函数transform(),它有两个类型参数,它将A 类型的参数转换为B 类型。

declare const transform: <A, B>(x: A) => A | B

const a = 123 //: number
const b = transform<number, string>(a) //: string

现在,我必须传入两种类型,但可以从参数中推断出第一种类型。我想要一个只需要新类型作为具体输入的函数。

如何编写一个接受一种具体类型并推断另一种的通用函数?


编辑 1

transform() 函数背后的实现并不重要。相反,我需要的是一种编写泛型函数的方法,该函数推断一种类型(在本例中为参数)并接受另一种类型(返回类型)。


编辑 2

我目前的替代方法是使用一个高阶函数(捕获返回类型),该函数返回另一个执行转换的函数。

declare const transform: <B>() => <A>(x: A) => A | B

const a = 123 //: number
const b = transform<string>()(a) //: string

编辑 3

transform()添加示例实现

const transform: <A, B>(x: A) => A | B = (x) => {
  if (x === null) {
    return null
  }

  if (typeof x === 'number') {
    return x.toString() as any
  }

  return x
}

const a = transform<number, string>(123)
const b = transform<null, boolean>(null)

【问题讨论】:

  • transform() 函数背后的实现并不重要” 我认为它是(或者更确切地说,一些MCVE),尤其是因为我不能看看在运行时不知道要转换的类型时如何正确实现转换。
  • 示例实现假定输入类型为number,输出类型为String。但是,虽然您可以在运行时知道前者,但您无法知道后者,所以...?这个函数解决了什么问题?
  • @T.J.Crowder 这就是我避免提供具体实现的原因。我的主要目标是实现类似于TypeScript#26349 但没有添加语法的东西。但是一旦函数定义出现,它就会克服潜在的问题。也许transform() 函数在这里只是错误的选择。

标签: typescript types typescript-generics


【解决方案1】:

接受它为any(或您希望它接受的类型的联合):

function transform<T>(x: any): T {
  return x
}

const a = 123 //: number
const b = transform<string>(a) //: string

但是,值得注意的是该函数实际上并没有转换任何东西。在您的示例中,虽然 TypeScript 认为 b 是一个字符串,但 它不是。它仍然是一个数字。您的函数在运行时根本不做任何事情。如果您想真正进行转换,您需要在运行时做一些事情来实现它。 您的编辑表明您知道这一点。 :-)

【讨论】:

  • 尽管transform() 函数是一个简单的类型转换,我还是用它作为一个简单的例子。该函数的作用不是重点,而是编写一个推断参数并接受返回类型的通用函数。
  • @zhirzh - 酷。 :-) 以上就是这样做的。
  • @t-j-crowder 我已经更新了问题以澄清我想要做什么。
  • @zhirzh - 我看不出高阶函数与any 相比对你有什么作用。您仍然无法编写依赖于参数类型的代码(没有运行时检查,这会自动为您缩小any)。
  • @t-j-crowder 更新了代码 sn-ps 并修改了返回类型。现在,作为示例,type Atype B 都是必需的。
猜你喜欢
  • 2020-06-24
  • 1970-01-01
  • 2011-10-06
  • 2019-12-06
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2020-08-21
  • 2023-03-27
相关资源
最近更新 更多