reactjs - 如何让 TypeScript 知道我正在使用哪些 proptypes?
问题描述
如何让 TypeScript 知道组件正在接收哪些道具类型?例如,如果multiple
是真的,我希望 TypeScript 期望这selectValue
是一个字符串数组,或者如果它不存在,那么 TypeScript 应该期望selectValue
是一个字符串。
我真的不喜欢必须将我的道具转换为合适的类型才能让 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>
解决方案
我就是这样做的。通过定义类型,TypeScript 可以知道 selectValue 的类型和其他可能会改变的类型。
import React, { ReactNode } from 'react';
import MultipleSelect from './MultipleSelect';
import SingleSelect from './SingleSelect';
type SelectProps = {
kind: 'multiple',
selectValue: string[];
onSelectChange: (values: string[]) => void;
renderValue?: (value: string[]) => React.ReactNode;
} | {
kind: 'single',
selectValue: string;
onSelectChange: (values: string) => void;
renderValue?: (value: string) => React.ReactNode;
}
const Selector = (props: SelectProps, children): JSX.Element => {
return (
<>
{
props.kind === 'multiple'
?
<MultipleSelect
selectValue={props.selectValue}
onSelectChange={props.onSelectChange}
renderValue={props.renderValue}
>
{children}
</MultipleSelect>
:
<SingleSelect
selectValue={props.selectValue}
onSelectChange={props.onSelectChange}
renderValue={props.renderValue}
>
{children}
</SingleSelect>
}
</>
)
}
export default Selector
推荐阅读
- python - 如何根据熊猫中另一列中的唯一值创建升序值列
- powershell - 为什么powershell找不到这个项目?
- python - 函数的变量如何具有参数?
- r - 如何从数据框列表中生成具有混合 ggplot2 和表输出的 rmarkdown pdf
- image - 如何查看图像中每个像素的排列矩阵
- windows - 专用网络中 Windows 上的电子自动更新
- amazon-web-services - 尝试从 s3 列出/放置/删除对象时拒绝 NiFi 访问
- php - PHP表单使用相同的表单添加和更新记录取决于查询参数
- python - 在同一程序中依次编译多个模型时精度低
- r - R中的快速循环和调节;根据另一列在列中插入新值