有没有一种方法可以覆盖打字稿中的界面类型?

时间:2019-02-14 12:45:33

标签: reactjs typescript react-native

我正在尝试进入TS,并将其添加到我的React Native应用中。

假设我有一个像这样的组件:

interface Props {
  name: string;
  onChangeText: (args: { name: string; value: string }) => void;
  style: ReactNative.TextStyle;
}

export class Input extends React.Component<Props, {}> {
  static defaultProps = {
    onChangeText: null,
    style: {},
  };

  handleTextChange = (text: string) => {
    const { name, onChangeText } = this.props;
    if (onChangeText) {
      onChangeText({ name, value: text });
    }
  };

  render() {
    const { style: propsStyle, onChangeText, ...restProps } = this.props;
    return (
      <ReactNative.TextInput
        style={[style, propsStyle]}
        onChangeText={this.handleTextChange}
        {...restProps}
      />
    );
  }
}

但是,如果我尝试以这种方式使用此组件:

<Input
  name='title'
  value={this.state.title}
  onChangeText={this.handleFieldChange}
/>

我遇到错误:

  

类型'IntrinsicAttributes和IntrinsicClassAttributes ...上不存在属性'value'

但是我无法从Props继承ReactNative.TextInputProps,因为在这种情况下,我将覆盖onChangeText的界面并开始出现另一个错误。
那么,有没有办法做到这一点?

2 个答案:

答案 0 :(得分:1)

您可以做类似的事情

type BaseProps = ReactNative.TextInputProps;
interface Props extends BaseProps {
  name: string;
  onChangeText: (args: { name: string; value: string }) => void;
  style: ReactNative.TextStyle;
}

如果您的自定义属性与基本属性冲突,则可以从扩展界面中将其删除:

type BaseProps = Pick<ReactNative.TextInputProps, Exclude<keyof ReactNative.TextInputProps, "name" | "onChangeText">>;
interface Props extends BaseProps {

关于Pick<..., Exclude<...>>(又称Omit<>)的更多信息是here

答案 1 :(得分:0)

如果您在界面上定义了索引签名,则可以给它提供任何支持,只要它与签名类型匹配即可:

interface TextStyle { fontSize: number }

interface Args {
  name: string;
  value: string;
}

type onChangeText = (args: Args) => void;

interface Props {
  [key: string]: string | TextStyle | onChangeText;
  name: string;
  onChangeText(args: { name: string; value: string }): void;
  style?: TextStyle;
}

现在

const props: Props = {
  name: 'title', 
  onChangeText: ({name, string}) => false,
  value: 'value' // <- no error 
}

但是请注意,这样的操作将会失败:

const props: Props = {
  name: 'title', 
  onChangeText: ({name, string}) => false,
  value: 10 // <- cannot be assigned
}

除非您将索引签名更新为包括该类型