【发布时间】:2021-09-15 11:26:50
【问题描述】:
如何让 TypeScript 知道组件正在接收哪些 prop 类型?
例如,如果 multiple 为真,我希望 TypeScript 期望 selectValue 是一个字符串数组,或者如果它不存在,那么 TypeScript 应该期望 selectValue 是一个字符串。
我真的不喜欢将我的 props 转换为合适的类型才能让 TypeScript 满意。
这是我的自定义 <Select> 组件的当前代码:
import React, { ReactNode } from 'react';
import MultipleSelect from './MultipleSelect';
import SingleSelect from './SingleSelect';
interface MultipleSelectProps {
selectValue: string[];
multiple: true;
onSelectChange: (values: string[]) => void;
renderValue?: (value: string[]) => React.ReactNode;
}
interface SingleSelectProps {
selectValue: string;
onSelectChange: (values: string) => void;
multiple?: never;
renderValue?: (value: string) => React.ReactNode;
}
type SelectProps = SingleSelectProps | MultipleSelectProps;
const Select: React.FC<SelectProps> = ({
selectValue,
multiple,
onSelectChange,
renderValue,
children,
}) => {
if (multiple) {
const multipleSelectValue = selectValue as string[];
const multipleSelectChange = onSelectChange as (value: string[]) => void;
const multipleRenderValue = renderValue as (value: string[]) => ReactNode;
return (
<MultipleSelect
selectValue={multipleSelectValue}
onSelectChange={multipleSelectChange}
renderValue={multipleRenderValue}
>
{children}
</MultipleSelect>
);
}
const singleSelectValue = selectValue as string;
const singleSelectChange = onSelectChange as (value: string) => void;
const singleRenderValue = renderValue as (value: string) => ReactNode;
return (
<SingleSelect
selectValue={singleSelectValue}
onSelectChange={singleSelectChange}
renderValue={singleRenderValue}
>
{children}
</SingleSelect>
);
};
export default Select;
我想写成这样:
import React, { ReactNode } from 'react';
import MultipleSelect from './MultipleSelect';
import SingleSelect from './SingleSelect';
interface MultipleSelectProps {
selectValue: string[];
multiple: true;
onSelectChange: (values: string[]) => void;
renderValue?: (value: string[]) => React.ReactNode;
}
interface SingleSelectProps {
selectValue: string;
onSelectChange: (values: string) => void;
multiple?: never;
renderValue?: (value: string) => React.ReactNode;
}
type SelectProps = SingleSelectProps | MultipleSelectProps;
const Select: React.FC<SelectProps> = ({
selectValue,
multiple,
onSelectChange,
renderValue,
children,
}) => {
return (
{
multiple ?
<MultipleSelect
selectValue={selectValue}
onSelectChange={onSelectChange}
renderValue={renderValue}
>
{children}
</MultipleSelect>
:
<SingleSelect
selectValue={selectValue}
onSelectChange={onSelectChange}
renderValue={renderValue}
>
{children}
</SingleSelect>
);
};
export default Select;
并且我希望能够像使用原生 html <select> 一样使用我的组件。像这样:
<Select selectValue={selectValue} onSelectChange={onSelectChange} multiple>
{options}
</Select>
【问题讨论】:
标签: reactjs typescript