[React Typescript] Strongly type Shared props for multiple components (React.FC<propsType>)

发布时间 2023-08-29 14:36:11作者: Zhentiw
import { Equal, Expect } from "../helpers/type-utils";

type InputProps = React.ComponentProps<"input">;

const COMPONENTS = {
  text: (props) => {
    return <input {...props} type="text" />;
  },
  number: (props) => {
    return <input {...props} type="number" />;
  },
  password: (props) => {
    return <input {...props} type="password" />;
  },
} satisfies Record<string, (props: InputProps) => JSX.Element>;

export const Input = (
  props: Record<"type", keyof typeof COMPONENTS> & InputProps
) => {
  const Component = COMPONENTS[props.type];
  return <Component {...props} />;
};

<>
  <Input
    type="number"
    onChange={(e) => {
      // e should be properly typed!
      type test = Expect<Equal<typeof e, React.ChangeEvent<HTMLInputElement>>>;
    }}
  ></Input>
  <Input type="text"></Input>
  <Input type="password"></Input>

  {/* @ts-expect-error */}
  <Input type="email"></Input>
</>;

 

  • Get the props for input, we can using React.ComponentProps<"input">
  • Improve: (props: InputProps) => JSX.Elementto React.FC<InputProps>
const COMPONENTS = {
  text: (props) => {
    return <input {...props} type="text" />;
  },
  number: (props) => {
    return <input {...props} type="number" />;
  },
  password: (props) => {
    return <input {...props} type="password" />;
  },
} satisfies Record<string, React.FC<InputProps>>;