使用 TypeScript 升级 MUI 4 - 无法正确地将道具传播到 TextField
MUIv4 Upgrade w/ TypeScript - Cannot spread props to TextField Properly
当前Material-UI版本:4.1.0
我在将 props 传播到我创建的抽象 <TextField />
组件时遇到问题。
代码如下:
PasswordInput.tsx
import * as React from 'react'
import TextField, { Props as TextFieldProps } from 'src/TextField'
type Props = TextFieldProps & {
hideHelperText?: boolean;
};
class PasswordInput extends React.Component<Props> {
onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
/** do stuff */
};
render() {
const {
hideHelperText,
classes,
...rest
} = this.props;
return (
<React.Fragment>
<TextField
/** errors out here */
/*
Type 'HideShowText | null' is not assignable to type 'HTMLDivElement | null'.
Type 'HideShowText' is missing the following properties from type 'HTMLDivElement':
align, addEventListener, removeEventListener, accessKey, and 238 more
*/
{...rest}
onChange={this.onChange}
/>
{!hideHelperText && 'hello world'}
</React.Fragment>
);
}
}
export default PasswordInput;
TextField.tsx
import TextField, {
StandardTextFieldProps as TextFieldProps
} from '@material-ui/core/TextField';
type ClassNames =
| 'root'
const styles = (theme: Theme) =>
createStyles({
root: {},
});
interface BaseProps {
tooltipText?: string;
dataAttrs?: Record<string, any>
}
export type Props = BaseProps & TextFieldProps
type CombinedProps = Props &
WithStyles<ClassNames>;
class MyTextField extends React.Component<CombinedProps> {
render() {
const {
children,
tooltipText,
dataAttrs,
/** everything else that goes on the root */
...textFieldProps
} = this.props;
return (
<div
>
<TextField
{...textFieldProps}
{...dataAttrs}
>
{this.props.children}
</TextField>
{tooltipText && <HelpIcon text={tooltipText} />}
</div>
);
}
}
const styled = withStyles(styles);
export default compose<CombinedProps, Props>(
styled
)(MyTextField);
正在轰炸,出现以下错误:
TS2322: Type '{ tooltipText: string | undefined; value: string | undefined; onChange: (e: ChangeEvent<HTMLInputElement>) => void; fullWidth: true; required: boolean | undefined; errorText?: string | undefined; ... 282 more ...; innerRef?: ((instance: any) => void) | ... 2 more ... | undefined; }' is not assignable to type 'IntrinsicClassAttributes<HideShowText>'.
Types of property 'ref' are incompatible.
Type '((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined' is not assignable to type 'string | ((instance: HideShowText | null) => void) | RefObject<HideShowText> | null | undefined'.
Type '(instance: HTMLDivElement | null) => void' is not assignable to type 'string | ((instance: HideShowText | null) => void) | RefObject<HideShowText> | null | undefined'.
Type '(instance: HTMLDivElement | null) => void' is not assignable to type '(instance: HideShowText | null) => void'.
Types of parameters 'instance' and 'instance' are incompatible.
Type 'PasswordInput | null' is not assignable to type 'HTMLDivElement | null'.
Type 'PasswordInput' is missing the following properties from type 'HTMLDivElement': align, addEventListener, removeEventListener, accessKey, and 238 more.
看来 PasswordInput 中的 ...rest
应该等于 StandardTextFieldProps
但由于某些原因,我的组件不是 HTMLDivElement
?
如果我可以提供更多详细信息,请告诉我。据我所知,这是一个错误。
我昨天 运行 遇到了这个确切的错误。我在其他地方做相同类型的联合,例如 SelectProps
,没有问题,但是 TextFieldProps
在多个属性上有问题,而 StandardTextFieldProps
只在 ref
上。因此,作为一项临时措施,您可以声明:
export type MyTextFieldProps = Omit< StandardTextFieldProps, 'ref' > & { ... }
@flatline。感谢您的建议。我还有一个改变导出方式的有效解决方案。老实说,我不确定为什么会这样,但确实如此。记下每个文件中的最后几行:
TextField.tsx
import TextField, {
StandardTextFieldProps as TextFieldProps
} from '@material-ui/core/TextField';
type ClassNames =
| 'root'
const styles = (theme: Theme) =>
createStyles({
root: {},
});
interface BaseProps {
tooltipText?: string;
dataAttrs?: Record<string, any>
}
export type Props = BaseProps & TextFieldProps
type CombinedProps = Props &
WithStyles<ClassNames>;
class MyTextField extends React.Component<CombinedProps> {
render() {
const {
children,
tooltipText,
dataAttrs,
/** everything else that goes on the root */
...textFieldProps
} = this.props;
return (
<div
>
<TextField
{...textFieldProps}
{...dataAttrs}
>
{this.props.children}
</TextField>
{tooltipText && <HelpIcon text={tooltipText} />}
</div>
);
}
}
const styled = withStyles(styles);
export default compose<CombinedProps, Props>(
styled
)(MyTextField) as s React.ComponentType<Props>;;
PasswordInput.tsx
import * as React from 'react'
import TextField, { Props as TextFieldProps } from 'src/TextField'
type Props = TextFieldProps & {
hideHelperText?: boolean;
};
class PasswordInput extends React.Component<Props> {
onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
/** do stuff */
};
render() {
const {
hideHelperText,
classes,
...rest
} = this.props;
return (
<React.Fragment>
<TextField
/** errors out here */
/*
Type 'HideShowText | null' is not assignable to type 'HTMLDivElement | null'.
Type 'HideShowText' is missing the following properties from type 'HTMLDivElement':
align, addEventListener, removeEventListener, accessKey, and 238 more
*/
{...rest}
onChange={this.onChange}
/>
{!hideHelperText && 'hello world'}
</React.Fragment>
);
}
}
export default PasswordInput as React.ComponentType<Props>;;
当前Material-UI版本:4.1.0
我在将 props 传播到我创建的抽象 <TextField />
组件时遇到问题。
代码如下:
PasswordInput.tsx
import * as React from 'react'
import TextField, { Props as TextFieldProps } from 'src/TextField'
type Props = TextFieldProps & {
hideHelperText?: boolean;
};
class PasswordInput extends React.Component<Props> {
onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
/** do stuff */
};
render() {
const {
hideHelperText,
classes,
...rest
} = this.props;
return (
<React.Fragment>
<TextField
/** errors out here */
/*
Type 'HideShowText | null' is not assignable to type 'HTMLDivElement | null'.
Type 'HideShowText' is missing the following properties from type 'HTMLDivElement':
align, addEventListener, removeEventListener, accessKey, and 238 more
*/
{...rest}
onChange={this.onChange}
/>
{!hideHelperText && 'hello world'}
</React.Fragment>
);
}
}
export default PasswordInput;
TextField.tsx
import TextField, {
StandardTextFieldProps as TextFieldProps
} from '@material-ui/core/TextField';
type ClassNames =
| 'root'
const styles = (theme: Theme) =>
createStyles({
root: {},
});
interface BaseProps {
tooltipText?: string;
dataAttrs?: Record<string, any>
}
export type Props = BaseProps & TextFieldProps
type CombinedProps = Props &
WithStyles<ClassNames>;
class MyTextField extends React.Component<CombinedProps> {
render() {
const {
children,
tooltipText,
dataAttrs,
/** everything else that goes on the root */
...textFieldProps
} = this.props;
return (
<div
>
<TextField
{...textFieldProps}
{...dataAttrs}
>
{this.props.children}
</TextField>
{tooltipText && <HelpIcon text={tooltipText} />}
</div>
);
}
}
const styled = withStyles(styles);
export default compose<CombinedProps, Props>(
styled
)(MyTextField);
正在轰炸,出现以下错误:
TS2322: Type '{ tooltipText: string | undefined; value: string | undefined; onChange: (e: ChangeEvent<HTMLInputElement>) => void; fullWidth: true; required: boolean | undefined; errorText?: string | undefined; ... 282 more ...; innerRef?: ((instance: any) => void) | ... 2 more ... | undefined; }' is not assignable to type 'IntrinsicClassAttributes<HideShowText>'.
Types of property 'ref' are incompatible.
Type '((instance: HTMLDivElement | null) => void) | RefObject<HTMLDivElement> | null | undefined' is not assignable to type 'string | ((instance: HideShowText | null) => void) | RefObject<HideShowText> | null | undefined'.
Type '(instance: HTMLDivElement | null) => void' is not assignable to type 'string | ((instance: HideShowText | null) => void) | RefObject<HideShowText> | null | undefined'.
Type '(instance: HTMLDivElement | null) => void' is not assignable to type '(instance: HideShowText | null) => void'.
Types of parameters 'instance' and 'instance' are incompatible.
Type 'PasswordInput | null' is not assignable to type 'HTMLDivElement | null'.
Type 'PasswordInput' is missing the following properties from type 'HTMLDivElement': align, addEventListener, removeEventListener, accessKey, and 238 more.
看来 PasswordInput 中的 ...rest
应该等于 StandardTextFieldProps
但由于某些原因,我的组件不是 HTMLDivElement
?
如果我可以提供更多详细信息,请告诉我。据我所知,这是一个错误。
我昨天 运行 遇到了这个确切的错误。我在其他地方做相同类型的联合,例如 SelectProps
,没有问题,但是 TextFieldProps
在多个属性上有问题,而 StandardTextFieldProps
只在 ref
上。因此,作为一项临时措施,您可以声明:
export type MyTextFieldProps = Omit< StandardTextFieldProps, 'ref' > & { ... }
@flatline。感谢您的建议。我还有一个改变导出方式的有效解决方案。老实说,我不确定为什么会这样,但确实如此。记下每个文件中的最后几行:
TextField.tsx
import TextField, {
StandardTextFieldProps as TextFieldProps
} from '@material-ui/core/TextField';
type ClassNames =
| 'root'
const styles = (theme: Theme) =>
createStyles({
root: {},
});
interface BaseProps {
tooltipText?: string;
dataAttrs?: Record<string, any>
}
export type Props = BaseProps & TextFieldProps
type CombinedProps = Props &
WithStyles<ClassNames>;
class MyTextField extends React.Component<CombinedProps> {
render() {
const {
children,
tooltipText,
dataAttrs,
/** everything else that goes on the root */
...textFieldProps
} = this.props;
return (
<div
>
<TextField
{...textFieldProps}
{...dataAttrs}
>
{this.props.children}
</TextField>
{tooltipText && <HelpIcon text={tooltipText} />}
</div>
);
}
}
const styled = withStyles(styles);
export default compose<CombinedProps, Props>(
styled
)(MyTextField) as s React.ComponentType<Props>;;
PasswordInput.tsx
import * as React from 'react'
import TextField, { Props as TextFieldProps } from 'src/TextField'
type Props = TextFieldProps & {
hideHelperText?: boolean;
};
class PasswordInput extends React.Component<Props> {
onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
/** do stuff */
};
render() {
const {
hideHelperText,
classes,
...rest
} = this.props;
return (
<React.Fragment>
<TextField
/** errors out here */
/*
Type 'HideShowText | null' is not assignable to type 'HTMLDivElement | null'.
Type 'HideShowText' is missing the following properties from type 'HTMLDivElement':
align, addEventListener, removeEventListener, accessKey, and 238 more
*/
{...rest}
onChange={this.onChange}
/>
{!hideHelperText && 'hello world'}
</React.Fragment>
);
}
}
export default PasswordInput as React.ComponentType<Props>;;