#reactjs #typescript
Вопрос:
У меня есть компонент списка
type Option = {
id: string;
};
type Props<O> = {
options?: O[];
option?: JSXElementConstructor<O>;
};
const List = <O extends Option>(props: Props<O>) => ...
и некоторые дополнительные компоненты, такие как этот
type Props = {
label: string;
icon?: ElementType;
onClick?: () => void;
};
const BasicOption = (props: Props) => ...
чтобы получить правильный тип, я должен сделать это
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}
/>
);
};
есть ли способ получить правильный ввод непосредственно из массива, чтобы избежать <typeof options[number]>
части?
Рабочий пример: https://codesandbox.io/s/vigorous-hopper-i41uj?file=/src/App.tsx
Комментарии:
1. Пожалуйста, поделитесь воспроизводимым примером.
JSXElementConstructor
,ElementType
? Это будет лучшее, что вы можете сделать, поделившись им на игровой площадке TS2. @капитан-йоссариан закончил!
Ответ №1:
Вам нужно сделать вывод options
и связать его 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 amp;amp; <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 amp;amp;
options amp;amp;
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} />
);
}
Вы можете найти больше о выводе аргументов функций в моем блоге
Комментарии:
1. TS может сделать вывод об этом из […Вариантов][числа], отлично!