代码之家  ›  专栏  ›  技术社区  ›  Barry Michael Doyle

如何在React组件道具中传递泛型类型

  •  1
  • Barry Michael Doyle  · 技术社区  · 2 年前

    我有一个组件,它采用一组选项,定义如下:

    interface Props {
      options: {
        label: string;
        value: string;
      }[]
    }
    function MyComponent(props: Props) {...}
    

    并且是这样实现的:

    <MyComponent
      options={[
        { label: "Right Hand", value: "RIGHT" },
        { label: "Left Hand", value: "LEFT" }
      ]}
    />
    

    在这个例子中,我给出了选择优势手的选项,我定义了一种类型,如下所示:

    type DominantHand = "RIGHT" | "LEFT"
    

    有可能使 MyComponent 灵活地指定选项的类型?

    我试着按照以下方式完成这项工作,但显然这里的语法不正确:

    type DominantHand = "RIGHT" | "LEFT"
    type Gender = "MALE" | "FEMALE"
    
    interface Props {
      options<T>: { // this syntax is wrong
        label: string;
        value: T;
      }[]
    }
    function MyComponent(props: Props) {...}
    
    ...
    
    <MyComponent
      options<DominantHand>={[ // <--- this syntax is wrong
        { label: "Right Hand", value: "RIGHT" },
        { label: "Left Hand", value: "LEFT" }
      ]}
    />
    <MyComponent
      options<Gender>={[ // <--- this syntax is wrong
        { label: "Male", value: "MALE" },
        { label: "Female", value: "FEMALE" }
      ]}
    />
    

    有办法做到这一点吗?

    4 回复  |  直到 2 年前
        1
  •  20
  •   sm3sher    2 年前

    在我阅读了之后 official typescript documentation 我建议如下:

    function MyComponent<T>(props: {
      options: {
        label: string;
        value: T;
      }[];
    }) {
      return <div>MyComponent</div>;
    }
    
    
    type DominantHand = "RIGHT" | "LEFT";
    
    function ParentComponent() {
      return (
        <MyComponent<DominantHand>
          options={[
            { label: "Right Hand", value: "RIGHT" },
            { label: "Left Hand", value: "LEFT" },
          ]}
        />
      );
    };
    
    
        2
  •  1
  •   Biskrem Muhammad    2 年前

    应该在接口本身中定义泛型,以便将其传递给内部的对象。

    所以应该是这样的:

    interface Props<T> {
      options: {
        label: string;
        value: T;
      }[]
    }
    function MyComponent(props: Props<string>) {...}
    
        3
  •  0
  •   Aleksa Djukic    2 年前

    尝试使用

    interface Props<T> {
      options: <T>[]
    }
    

    然后你可以创建一个单独的选项对象,并像这样传递它

    interface GenericPropObject {
    ....
    }
    
    function MyComponent(props: Props<GenericPropObject>) {...}
    
        4
  •  -1
  •   Henry Obiaraije    2 年前

    这里有一个 先进的 做这件事的方式(我在当前的项目中做了这件事)

    这里,我有一个React组件 TextInput 显示类型的输入 text , password email .

    但是,我想 给任何使用此组件的人一个选项,以确保提供 name 用于输入 匹配其表单名称 .

    所以,我的注册表格名称 types 看起来像这样。( 我是这样做的,所以我可以通过使用每个输入组件在输入时提供的名称,用来自一个函数的所有输入的值来更新状态 ).

    type SignupInputNamesTypes =
      | "email"
      | "username"
      | "first_name"
      | "last_name"
      | "password"
      | "password_confirm"
      | "referrer";
    

    然后 文本输入框 道具。

    export interface TextInputProps<NameTypes> {
     name: NameTypes;
     type: "text" | "password" | "email";
    ...
    ...
    ...
    }
    

    然后 文本输入框 组件本身

    export default function TextInput<NameTypes>({
      label,
      name,
      value = "",
      type = "text",
      infoText = "",
      showChecked = false,
      handleChange,
      required = false,
      cssClasses,
    }: TextInputProps<NameTypes>): JSX.Element {
      return (
        <>
         ...
         ...
         ...
        </>
    )};
    

    所以使用 文本输入框 组件,你可以这样做

    <TextInput<SignupInputNamesTypes>
              type="text"
              cssClasses="flex-1"
              value={state.first_name}
              label={__("First Name", "referrer-plugin")}
              name="first_name"
              handleChange={(value, event) => {
                handleChange("first_name", value);
              }}
              required
            />
    

    注意 我在这里做了什么 <TextInput<SignupInputNamesTypes> 我现在可以通过我的 type 的泛型 文本输入框 组件,然后用于设置可接受的 名称 类型。

    它的构建是,在使用时甚至不需要传递泛型 文本输入框 组成部分

    我希望这能帮助到其他人。

    这就是故事书上的样子。

    enter image description here