1

当前 Material-UI 版本:4.1.0

我在将道具传播到<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.

看来...restPasswordInput 中的 应该等于 ,StandardTextFieldProps但由于某种原因,我的组件不是HTMLDivElement?

让我知道我是否可以提供更多详细信息。据我所知,这是一个错误。

4

2 回答 2

1

@水平线。谢谢你的建议。我也有一个可行的解决方案来改变导出的输入方式。老实说,我不确定为什么会这样,但确实如此。记下每个文件中的最后几行:

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>;;
于 2019-06-14T03:14:40.783 回答
0

我昨天遇到了这个确切的错误。我在其他地方做相同类型的联合,例如 with SelectProps,没有问题,但TextFieldProps在多个属性和StandardTextFieldPropsjust上都有问题ref。因此,作为一项临时措施,您可以声明:

export type MyTextFieldProps = Omit< StandardTextFieldProps, 'ref' > & { ... }
于 2019-06-13T20:36:16.040 回答