Reputation: 16649
I've a List component
type Option = {
id: string;
};
type Props<O> = {
options?: O[];
option?: JSXElementConstructor<O>;
};
const List = <O extends Option>(props: Props<O>) => ...
and some option components like this one
type Props = {
label: string;
icon?: ElementType;
onClick?: () => void;
};
const BasicOption = (props: Props) => ...
in order to get the right type I have to do this
const Example = () => {
const options = [
{ id: 'a', label: 'Label A', icon: PlaceholderIcon },
{ id: 'b', label: 'Label B', icon: PlaceholderIcon },
{ id: 'c', label: 'Label C', icon: PlaceholderIcon },
{ id: 'd', label: 'Label D', disabled: true },
{ id: 'e', label: 'Label E' },
];
return (
<List<typeof options[number]>
options={options}
option={BasicOption}
/>
);
};
is there a way to get the right typing directly from the array in order to avoid the <typeof options[number]>
part?
Working example: https://codesandbox.io/s/vigorous-hopper-i41uj?file=/src/App.tsx
Upvotes: 3
Views: 903
Reputation: 33061
You need infer options
prop and bind it with option
.
import React, { JSXElementConstructor, ElementType } from "react";
export type BasicProps = {
label: string;
icon?: ElementType;
onClick?: () => void;
};
export const BasicOption = ({ label, icon: Icon, onClick }: BasicProps) => (
<div onClick={() => onClick?.()}>
{label}
{Icon && <Icon />}
</div>
);
export type Option = {
id: string;
};
export const List = <Opt extends Option, Options extends Opt[]>({
options,
option: Option
}: {
options: [...Options],
// same as typeof options[number] but Options is infered
option: JSXElementConstructor<[...Options][number]>;
}) => (
<div>
{Option &&
options &&
options.map((option) => <Option key={option.id} {...option} />)}
</div>
);
export default function App() {
const options = [
{ id: "a", label: "Label A" },
{ id: "b", label: "Label B" },
{ id: "c", label: "Label C" },
{ id: "d", label: "Label D", disabled: true },
{ id: "e", label: "Label E" }
];
return (
<List options={options} option={BasicOption} />
);
}
You can find more about function arguments inference in my blog
Upvotes: 1