如何从包装的React组件中传入material-ui TextField的variant属性

时间:2019-04-13 10:22:32

标签: reactjs typescript material-ui

我遇到打字问题...

基本上,我为@ material-ui TextField提供了一个包装的React组件,但我无法正确获取variant属性的类型。

这是问题的要点。 @ material-ui / core为3.9.3

import MuiTextField, {TextFieldProps} from "@material-ui/core/TextField";

interface MyTextFieldProps {
...
  variant?: TextFieldProps["variant"];
}

class MyTextField extends React.Component<MyTextFieldProps> {
...
  render() {

    return
    ...other stuff
      <MuiTextField
      variant={this.props.variant} />
    ...;
  }
}

对于MuiTextField实例,出现以下编译错误: ...

Types of property 'variant' are incompatible.
        Type '"outlined" | "filled"' is not assignable to type '"outlined"'.
          Type '"filled"' is not assignable to type '"outlined"'.

我可以将其进一步简化为道具类型:

xx() {
    const variant: TextFieldProps["variant"] = this.props.variant;
    const props : TextFieldProps = {
      variant,
    };
}

并得到相同的错误,即变量值(键入为variant属性的确切类型)与其自己的类型不兼容。

这是怎么回事?

TextField.d.ts中的定义如下:


export interface StandardTextFieldProps extends BaseTextFieldProps {
  variant?: 'standard';
  InputProps?: Partial<StandardInputProps>;
  inputProps?: StandardInputProps['inputProps'];
}

export interface FilledTextFieldProps extends BaseTextFieldProps {
  variant: 'filled';
  InputProps?: Partial<FilledInputProps>;
  inputProps?: FilledInputProps['inputProps'];
}

export interface OutlinedTextFieldProps extends BaseTextFieldProps {
  variant: 'outlined';
  InputProps?: Partial<OutlinedInputProps>;
  inputProps?: OutlinedInputProps['inputProps'];
}

export type TextFieldProps = StandardTextFieldProps | FilledTextFieldProps | OutlinedTextFieldProps;

更新

正如丹尼尔指出的那样,这是Typescript,不知道如何处理联合类型。

您可以使用这样的帮助程序功能来解决此问题(难看)

import { TextFieldProps, BaseTextFieldProps } from "@material-ui/core/TextField";

const getProps = (
  baseProps: BaseTextFieldProps,
  variant: TextFieldProps["variant"]
): TextFieldProps => {
  switch (variant) {
    case "filled":
      return { ...baseProps, variant };
    case "outlined":
      return { ...baseProps, variant };
    default:
      return { ...baseProps, variant };
  }
};

然后将其用作<TextField ...getProps({value:"text"}, variant) />,但它很丑。

我什至会把这归类为打字稿问题,因为它应该能够弄清楚所有不同变体所独有的道具都是可选的。

2 个答案:

答案 0 :(得分:1)

我有完全相同的问题。

错误的原因是他们已经定义

TextFieldProps = StandardTextFieldProps | FilledTextFieldProps | OutlinedTextFieldProps

OutlinesTextFieldProps需要变量的值为'outlined' FilledTextFieldProps需要变量的值为“已填充”

问题是在编译时不知道variant的值。在您的代码中,它是一个变量,因此其类型为'filled' | 'outlined'。该类型与三个类型定义中的任何一个都不兼容,这三个类型定义均需要“概述”,“填充”或“标准”之一

除了as any技巧外,我唯一想到的另一种选择是使用变量的静态值实例化textfeilds,但这是很多额外的工作。像这样:

{ this.props.variant === 'outlined' && (
  <MuiTextField
    variant="outlined"
   />
)}
{ this.props.variant === 'filled' && (
  <MuiTextField
    variant="filled"
   />
)}


我将用material-ui提出一个有关此的错误。

答案 1 :(得分:0)

这可能不是正确的方法,但是要解决此问题,您可以将其强制转换为any

variant={this.props.variant as any}

我现在有同样的问题,找不到解决打字稿问题的方法。