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

6

我有打字问题……

基本上,我有一个用于@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,
    };
}

当您尝试将值赋给变体属性时,可能会遇到相同的错误,即变体值(其类型与变体属性的确切类型相符)与其自身类型不兼容。

这是怎么回事?

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;

更新

正如Daniel所指出的,这是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) />使用,但这很丑。

我甚至敢说这是一个TypeScript问题,因为它应该能够发现所有不同变体的唯一道具都是可选的。


请提供示例演示 - solanki...
2个回答

4

我有完全相同的问题。

错误的原因是他们定义了

TextFieldProps = StandardTextFieldProps | FilledTextFieldProps | OutlinedTextFieldProps

OutlinesTextFieldProps需要'outlined'作为变量值 FilledTextFieldProps需要'filled'作为变量值等等

问题在于variant的值在编译时不确定。在你的代码中,它是一个变量,因此其类型为'filled' | 'outlined'。该类型与三个类型定义中的任何一个都不兼容,每个定义都需要其中之一:'outlined'、'filled'或'standard'

除了使用 as any技巧外,我想到的唯一其他选项是使用静态值实例化文本字段,但这需要很多额外的工作。例如:

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


编辑-2019年03月06日

在material-ui的github上提出了一个bug,并发布了另一种可能的解决方案。

https://github.com/mui-org/material-ui/issues/15697#issuecomment-493419773


谢谢,我以为我要疯了 :) - Pelle
@Daniel van Berzon,您能否分享一下您提交的Github问题链接? - Josiah Nunemaker
@JosiahNunemaker 抱歉,我一直没有时间!我会尽量在今天完成并将链接发给你。 - Daniel van Berzon
1
@JosiahNunemaker 我找到了一个已关闭的工单,其中突出了相同的问题 https://github.com/mui-org/material-ui/issues/15697 - Daniel van Berzon

3

这可能不是正确的方法,但为了暂时解决问题,您可以将其转换为 any 类型。

variant={this.props.variant as any}

我目前也遇到了同样的问题,但无法找到适用于TypeScript的解决方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接