typescript - 在 typescript 中过滤keyof类型参数

标签 typescript types

无需了解 React,只需一些背景知识:在我的用例中,我想使用我的自定义高阶组件来扩展用户指定的 React.ComponentClass。为此,我希望用户还向我发送我的高阶组件将注入(inject)的特定 Prop 的名称列表。这将像这样完成:

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 不是接口(interface)的一部分 TestProps

问题是,我想限制 props参数不仅是TComponentProps的关键, 也是 TComponentProps 中相应类型的键是Function (因此 'a' 将是 typescript 编译器检测到的无效选项)。如何完成这样的任务?

最佳答案

你可以这样做:

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只有Function特性。当你真的想传递类似 listToComponentProps<TestProps>(['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

关于typescript - 在 typescript 中过滤keyof类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47359713/

相关文章:

reactjs - Next.js、TypeScript 和 tsconfig.json 'jsx' 属性被覆盖

mongodb - 问号 Typescript 变量

javascript - 如何在 Angular 和 Bootstrap 3.3.7 中应用父级和子级的复选框

angular - 从父级获取子级中的变量,从父组件触发它

c# - 将 base64string 转换为 Image 类型。找不到图像类型?

MySQL 主键字段类型

angular - 当我们输入 [Angular] 时,如何检测输入字段的变化

go - 验证 int 和 float64 的 reflect.Type 的其他方法

types - Rust 中的枚举与结构类型名称如何工作?

sql - 从 JSON 列计算平均值