4

我有打字问题...

基本上,我有一个用于 @material-ui TextField 的包装 React 组件,但我无法为变体属性正确输入类型。

这是问题的要点。@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) />但它很难看。

我什至敢于将其归类为打字稿问题,因为它应该能够确定不同变体独有的所有道具都是可选的。

4

2 回答 2

4

我也有完全一样的问题。

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

TextFieldProps = StandardTextFieldProps | FilledTextFieldProps | OutlinedTextFieldProps

OutlinesTextFieldProps 需要为变体提供“轮廓”值 FilledTextFieldProps 需要为变体提供“填充”值

等等

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

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

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


编辑 - 2019 年 3 月 6 日

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

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

于 2019-04-16T10:09:58.873 回答
2

这可能不是正确的方法,但现在要解决它,您可以将其转换为any.

variant={this.props.variant as any}

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

于 2019-04-15T07:49:43.690 回答