简体   繁体   English

有没有办法使用泛型来键入一个复杂的对象数组来准确比较 React 组件及其 props 类型?

[英]Is there a way to use generics to type a complex object array that accurately compares a React component and its props type?

My team has created typescript types definitions for an API that we're using, so we aren't able to touch the source code, just the definitions.我的团队为我们正在使用的 API 创建了 typescript 类型定义,因此我们无法触及源代码,只能触及定义。

We have a function called add that essentially adds one or more react components to the main program.我们有一个名为add的函数,它本质上是在主程序中添加一个或多个 React 组件。 The props property of the object should depend on the component type listed on the component property.对象的props属性应该取决于component属性上列出的组件类型。

It looks like this:它看起来像这样:

 add(arg1, arg2, { //some other args children: [{ id: string1, //BackButton can be a functional or class-based component component: BackButton, //BackButtonProps will be defined within BackButton props: BackButtonProps }, { id: string2, //SkipButton can be a functional or class-based component component: SkipButton, //SkipButtonProps will be defined within SkipButton props: SkipButtonProps } ] });

For reference, there is an alternate (overloaded) version of the function that only adds one component instead of multiple that I've been able to figure out the typescript for.作为参考,该函数有一个替代(重载)版本,它只添加一个组件,而不是多个我已经能够找出打字稿的组件。 It looks like this:它看起来像这样:

 add<T>( id: string, component: ComponentType<T>, props: T ): void;

My question is this -- since the number of children components is unknown, how can I use a generic on the add function so that all the children components are correctly typed (the props and component properties match up)?我的问题是——由于子组件的数量未知,我如何在add函数上使用泛型,以便正确键入所有子组件( propscomponent属性匹配)?

A generic signature of add would look like this. add的通用签名如下所示。

declare function add<T extends any[]>(arg1: any, arg2: any, arg3: {
    children: [...{ [K in keyof T]: {
      id: string,
      component: T[K]
      props: React.ComponentProps<T[K]>     
    }}]
}): void

The generic type T would store a tuple where each element is a react component.泛型类型T将存储一个元组,其中每个元素都是一个反应组件。 For each element with the index K of the passed array, the component type would be used as the type in T[K] and the props type would have to be React.ComponentProps<T[K]> .对于传递数组的索引为K的每个元素, component类型将用作T[K]中的类型,而props类型必须是React.ComponentProps<T[K]>

Let's see this in action:让我们看看它的实际效果:

const BackButton = (props: {a: string}) => {
    return <div></div>
}

const SkipButton = (props: {b: string}) => {
    return <div></div>
}

add(0, 0, {
    children: [
        {
            id: "1",
            component: BackButton,
            props: { a: "123" }
        },
        {
            id: "2",
            component: SkipButton,
            props: { b: "123" }
        },
        {
            id: "3",
            component: SkipButton,
            props: { a: "123" } // Error: Type '{ a: string; }' is not assignable to type '{ b: string; }'
        }
    ]
})

Playground 操场

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

相关问题 如何在功能组件的 React 中的 props 中使用 generics? - How to use generics in props in React in a functional component? TypeScript 泛型:React 中具有联合类型的道具 - TypeScript generics: Props with union type in React 为带有特定 props 的 React 组件输入类型 - Type for a React component with certain props 键入没有道具的 React 组件 class 的正确方法是什么? - What is the correct way to type a React component class that has no props? 如何在道具中使用 object 解构来声明功能性 React 组件的类型? - How to declare type for functional React component using object destructuring in props? 使用联合类型 generics 时推断单个类型(扩展反应组件道具) - Inferring individual types when using union type generics (extending react component props) 如何在反应组分的酶中设置对象类型道具值? - How to set object type props value in an enzyme for a react component? 如何将 React 中的类型用于我自己组件的道具? - How to use a type from React for props of my own component? 作为数组传递的道具在 Reactjs 的子组件中作为对象类型获取 - Props passed as array is getting as object type in the child component in Reactjs React和Typescript组件为`Component`提供道具类型 - React & Typescript component props type for `Component`
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM