【问题标题】:How to write omit function with proper types in typescript如何在打字稿中编写具有正确类型的省略函数
【发布时间】:2019-04-27 05:07:56
【问题描述】:

我最终想要做的是创建一个 React HOC,它将注入一个由字符串定义的属性并返回一个组件,而不需要注入的属性。本质上,这归结为返回省略函数的工厂函数。

正如你在这个例子中看到的那样,由于某种原因,类型 B 最终是“从不”。

const f = <A extends object, B extends keyof A>(arg: B) => (obj: A): Omit<A, B> => {
  delete obj[arg]
  return obj
}
// TS2345: Argument of type "test" is not assignable to parameter of type 'never'
const a = f('test')
const b = a({ test: 1})
const c = b.test

当我在泛型参数之外尝试 keyof 时,它似乎运行得更好,但打字稿不能正确推断返回类型,我不知道如何键入它,因为我不知道如何获取对第一个的引用可以在省略中使用的字符串 arg:

const f = <A extends object>(arg: keyof A) => (obj: A) => {
  delete obj[arg]
  return obj
}
const a = f('test')
const b = a({ test: 1 })
// Does not infer 'test' is no longer here
const c = b.test

供参考省略为:

export type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    由于第一个函数具有两个类型参数,因此 typescript 将尝试在调用发生时进行推断,并且由于没有 A 的推断站点,它可能会推断{},从而使B 永远不会。解决这个问题的方法是使B 发生第二次调用时推断A,约束条件是A 必须有一个B 键:

    export type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
    
    const f = <B extends keyof any>(arg: B) => <A extends Record<B, any>>(obj: A): Omit<A, B> => {
    delete obj[arg]
    return obj
    }
    
    const a = f('test')
    const b = a({ test: 1, other: ""})
    const c = b.test; // error as expected
    const c2 = b.other; // ok 
    

    【讨论】:

    • 非常感谢,这对您有很大帮助。我意识到我在 HOC 中还有一篇文章,我在问题中省略了。是否有可能以某种方式将A 类型反向传播到第一个函数调用。我想做的是&lt;B extends keyof any&gt;(arg: B, fn: (arg: A) =&gt; void) =&gt; ...。所以基本上,我给你属性名称和一个函数,它将接受我稍后会给你的对象。如果这没有意义,我可以创建新问题,我的错误是我没有意识到这很重要。
    • @aocenas 你能用完整的代码发布一个新问题吗?完整地看到它会更有意义.. cmets 不是很多代码的好地方..
    • 这是一个新问题,希望它有意义stackoverflow.com/questions/53470559/…
    猜你喜欢
    • 1970-01-01
    • 2021-07-05
    • 2020-02-22
    • 2019-12-25
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 2022-11-22
    相关资源
    最近更新 更多