我正在使用typescript
来执行React组件。我在定义泛型时遇到问题。下面是代码:
interface Props<T> {
classes: { [className in keyof typeof styles]: string };
style?: React.CSSProperties;
value?: T;
label: string;
onChange: (e: T) => void;
}
export const OutlinedInputField = withStyles(styles)(
<T extends string | number>({ classes, style, value, onChange, label }: Props<T>) => {
const type = typeof value === 'number' ? 'number' : 'text';
return (
<Grid className={classes.root} style={style}>
<TextField
value={value}
type={type}
variant="outlined"
label={label}
onChange={(e) => onChange(e.target.value as T)}
/>
</Grid>
);
}
);
上述组件的value属性需要通用类型。并且它使用此类型来确定它是数字还是文本Textfield
。我不了解如何使用此组件?
如果我通过以下方式使用此组件(value属性的类型为数字),则onChange
上的参数为number
或string
。它不限制类型为数字。如何在number
组件上强制使用类型OutlinedInputField
?
<OutlinedInputField value={value} label="Item weight (kg)" onChange={(n: number) => setValue(n)}/>
我尝试了下面的代码,但收到错误Expected 0 type arguments, but got 1.
。
<OutlinedInputField<number> value={value} label="Item weight (kg)" onChange={(n: number) => setValue(n)}/>
答案 0 :(得分:0)
我可以想到有两种选择可以实现这一目标:
export const OutlinedInputField = withStyles(styles)(
({ classes, style, value, onChange, label }: Props<string | number>) => {
const type = typeof value === "number" ? "number" : "text";
return (
<Grid className={classes.root} style={style}>
<TextField
value={value}
type={type}
variant="outlined"
label={label}
onChange={e => onChange(e.target.value as T)}
/>
</Grid>
);
}
) as <T extends number | string>(props: Props<T>) => any
用法
<OutlinedInputField<number> value={value} label="Item weight (kg)" onChange={(n: number) => setValue(n)}/>
export const createOutlinedInputField = <T extends number | string>() => {
const OutlinedInputField: React.FC<Props<T>> = ({ classes, style, value, onChange, label }) => {
const type = typeof value === "number" ? "number" : "text";
return (
<Grid className={classes.root} style={style}>
<TextField
value={value}
type={type}
variant="outlined"
label={label}
onChange={e => onChange(e.target.value as T)}
/>
</Grid>
);
};
return withStyles()(OutlinedInputField);
};
用法:
const OutlinedInputField = createOutlinedInputField<number>();
<OutlinedInputField value={value} label="Item weight (kg)" onChange={(n: number) => setValue(n)}/>