繁体   English   中英

在打字稿中过滤keyof类型参数

[英]Filter on keyof type parameter in typescript

无需了解React,只需了解一些背景知识:在我的用例中,我想使用自定义的Higher Order Component来放大用户指定的React.ComponentClass。 为此,我希望用户也向我发送我的高阶组件将注入的特定道具的名称列表。 可以这样做:

function listToComponentProps<TComponentProps, TKey = keyof TComponentProps>(props: Array<TKey>) {
  // Logic here, not important for the example
}
interface TestProps {a: number, b: Function, c: () => number}
listToComponentProps<TestProps>(['a', 'b', 'c'])

keyof关键字为我处理约束。 listToComponentProps<TestProps>示例输入为

  • 有效: ['b']['b', 'c']['c']
  • 无效
    • ['a']['a', 'b']['a', 'b', 'c'] (a是数字,不是函数)
    • ['d']['d', 'c'] (d不属于接口TestProps

问题是,我要限制的props参数不仅是关键TComponentProps ,而且这样的键,在对应类型TComponentPropsFunction (使得'a'将是由编译器的打字原稿检测到一个无效选项)。 一个人怎么能完成这样的任务?

您可以这样做:

const listToComponentProps = <
  TComponent extends {[P in TKey]: Function },
  TKey extends string = keyof TComponent>
  (props: TKey[]) => { /* ... */ };

interface TestProps {a: number, b: Function, c: () => number}
const result = listToComponentProps<TestProps>(['a', 'b', 'c']) // Type error

这导致类型错误:

Type 'TestProps' does not satisfy the constraint '{ a: Function; b: Function; c: Function; }'.
  Types of property 'a' are incompatible.
    Type 'number' is not assignable to type 'Function'.

不幸的是,这种使用默认参数的TComponent最终限制了我们的TComponent仅具有Function属性。 当您真正想要传递类似listToComponentProps<TestProps>(['b', 'c']) ,该内容应该是有效的,您将需要显式填写第二个类型参数,即listToComponentProps<TestProps, 'b' | 'c'>(['b', 'c']) listToComponentProps<TestProps, 'b' | 'c'>(['b', 'c'])

真正想要的是不具有缺省参数TKey ,而是用于一般推理,以颗粒状:在一个类型参数列表, 可以推断出所有参数(例如TKey ,这可以从传递的数组推断) 推断,即使必须手动指定一些(在这种情况下为TComponent )。 TypeScript目前无法以这种方式工作,所以我们是SOL。

在TypeScript问题跟踪器上有很多与此有关的未解决问题,您可以去查找它们并臭气熏天。


如果良好的推理对您而言比严格保留运行时特征更为重要,则可以添加一个虚拟参数来分离两个类型参数的推理:

const listToComponentProps =
    <TKey extends string>
    (props: TKey[]) =>
    <TComponent extends {[P in TKey]: Function }>
    () => { /* ... */ };

interface TestProps { a: number, b: Function, c: () => number }

const result = listToComponentProps(['a', 'b', 'c'])<TestProps>() // Type error
const result2 = listToComponentProps(['b', 'c'])<TestProps>() // OK

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM