【问题标题】:Type-safe curried function for extracting property from object in Typescript [duplicate]用于从 Typescript 中的对象中提取属性的类型安全柯里化函数 [重复]
【发布时间】:2019-08-24 18:59:49
【问题描述】:

我想为我的prop 函数添加类型。它被柯里化了(键在前,对象在后)。

我尝试了以下方法:在将其部分应用于某个键之后,我尝试将其限制为包含此类属性的对象。

我尝试通过以下方式实现它:

const prop = (key: string) =>
  <K, T extends { [key: string]: K }>(obj: T): K =>
  obj[key]

不幸的是,这种方法似乎不起作用。这是我预计会失败的代码(我还在a Typescript Playground 中包含了所有这些代码):

const getFoo = prop('foo')
getFoo({ fooo: 42 })

带有类似的错误消息

Error: type '{ fooo: number }' is not assignable to '{ foo: number }'

但事实并非如此(它会默默地失败)。 我还希望推断对象中的属性类型,因此此代码失败:

const someNumber: number = prop('foo')({ 'foo': 'abc' })

出现如下错误:

Error: type 'string' is not assignable to 'number'.

这是按预期工作的。但是,如果我省略了someNumber 上的类型注释,它就不会被推断出来,所以对于:

const someNumber = prop('foo')({ 'foo': 'abc' })

someNumber 的类型未知。 有没有办法满足所有这些限制?

我也一直在考虑“反过来”这样做,给出我们将首先处理的对象的类型,然后使用&lt;T, K extends keyof T&gt; 做一些事情,但这会迫使用户每次提供类型参数...

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    试试这个:

    const prop = <Key extends string>(key: Key) =>
      <T extends Record<Key, any>>(obj: T): T[Key] =>
      obj[key];
    
    const getFoo = prop('foo')
    const result: string = getFoo({ foo: 42 })
    

    【讨论】:

    • 谢谢。此解决方案有效,但不幸的是,它给出了提及Recordtype 的晦涩错误消息(对于不熟悉此特定实用程序类型的人来说,这可能会让人非常困惑)。但实际上您的解决方案帮助我开发了自己的解决方案,它只使用普通对象。我会在一分钟内发布它。
    【解决方案2】:

    我设法使用mapped types 开发解决方案:

    const prop = <K extends string>(key: K) =>
      <T extends { [k in K]: T[K] }>(obj: T): T[K] =>
      obj[key];
    

    链接到Typescript Playground

    【讨论】:

    • 好吧,Record 只是映射类型的内置别名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-25
    • 2018-02-05
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多