reactjs - Hvordan passer man dynamiske props til en React-komponent, der accepterer en union af objekter som dens type?
Jeg vil have en komponent til at videresende dynamiske props (jeg bruger spread-operatoren), og dette er den kode, jeg har lige nu:
type Props = {
identifier: "YouTube";
attributes: { id: string };
} | {
identifier: "Figure";
attributes: { src: string };
};
const YouTube = ({ id }) => <p>{id}</p>;
const Figure = ({ src }) => <p>{src}</p>;
const Shortcode = ({ identifier, attributes }: Props): JSX.Element => {
switch (identifier) {
case "YouTube":
return <YouTube {...attributes} />;
case "Figure":
return <Figure {...attributes} />;
}
};
TypeScript klager over dette:
return <YouTube {...attributes} />;
// Type '{ id: string; } | { src: string; }' is not assignable to type 'IntrinsicAttributes & { id: any; }'.
// Property 'id' is missing in type '{ src: string; }' but required in type '{ id: any; }'.ts(2322)
return <Figure {...attributes} />;
// Type '{ id: string; } | { src: string; }' is not assignable to type 'IntrinsicAttributes & { src: any; }'.
// Property 'src' is missing in type '{ id: string; }' but required in type '{ src: any; }'.ts(2322)
Hvis jeg eksplicit videregiver props, opfører TypeScript sig som forventet:
<YouTube id="foo" /> // TS says this is ok
<YouTube wrong="props" /> // TS says this is missing the `id` prop
Men jeg har brug for, at det kan acceptere dynamiske props. Nogle idéer til, hvordan man løser dette? Tak.
Svar #1
Dette skyldes destrukturering. TS behandler dem ikke som en del af en union.
For at gøre TS glad, skal du bare ikke bruge destrukturering:
import React, { FC } from 'react';
type Props = {
identifier: "YouTube";
attributes: { id: string };
} | {
identifier: "Figure";
attributes: { src: string };
};
const YouTube: FC<{ id: string }> = ({ id }) => <p>{id}</p>;
const Figure: FC<{ src: string }> = ({ src }) => <p>{src}</p>;
const Shortcode = (props: Props): JSX.Element => {
switch (props.identifier) {
case "YouTube":
return <YouTube {...props.attributes} />; // ok
case "Figure":
return <Figure {...props.attributes} />; // ok
}
};
