Обновление MUIv4 с TypeScript - не может правильно распространять реквизиты в TextField - PullRequest
1 голос
/ 12 июня 2019

Текущая версия 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.

Похоже, что ...restв поле PasswordInput должно быть равно StandardTextFieldProps, но по какой-то причине я получаю ошибки, поскольку мой компонент не является HTMLDivElement?

Дайте мне знать, если я смогу предоставить более подробную информацию.Насколько я могу судить, это ошибка.

Ответы [ 2 ]

0 голосов
/ 14 июня 2019

@ 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>;;
0 голосов
/ 13 июня 2019

Я столкнулся с этой ошибкой вчера.Я делаю такое же объединение типов в других местах, например, с SelectProps, без проблем, но TextFieldProps проблематично для нескольких свойств и StandardTextFieldProps только для ref.Поэтому в качестве временной меры вы можете объявить:

export type MyTextFieldProps = Omit< StandardTextFieldProps, 'ref' > & { ... }
...