typescript 如何在React组件props中传递泛型类型

4ioopgfo  于 2022-11-18  发布在  TypeScript
关注(0)|答案(4)|浏览(262)

我有一个组件,它接受一个选项数组,定义如下:

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" }
  ]}
/>

有没有办法做到这一点?

v440hwme

v440hwme1#

在阅读了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" },
      ]}
    />
  );
};
eagi6jfj

eagi6jfj2#

您应该在接口本身中定义泛型,这样它就可以向下传递到内部的对象。
所以应该是这样的:

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

wnavrhmk3#

试用

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

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

interface GenericPropObject {
....
}

function MyComponent(props: Props<GenericPropObject>) {...}
1rhkuytd

1rhkuytd4#

这里有一个有点先进的方法来做它(我在我正在做的当前项目中做的)
在这里,我有一个React组件TextInput,它显示textpasswordemail类型的输入。
但是,我想***为使用此组件的任何人提供一个选项,以确保为输入提供的***name***与他们的表单名称**匹配。
所以,我的注册表单名称types看起来像这样。(
我是这样做的,所以我可以使用来自一个函数的所有输入的值来更新状态,通过使用每个输入组件将在输入上提供的名称 *)。

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

然后,TextInput道具。

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

然后TextInput组件本身

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

因此,要使用TextInput组件,需要执行以下操作

<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泛型传递给TextInput组件,然后使用该组件设置可接受的name类型。

它的构建是,在使用TextInput组件时,甚至不需要沿着泛型。
我希望这对外面的人有帮助。
这是故事书上的样子。

相关问题