可分配给类型'P'的约束,但可以使用约束'TextInputProps'的其他子类型实例化'P'

时间:2020-03-18 07:51:20

标签: reactjs typescript

这是HOC,我有以下错误:

输入'Pick,“儿童” |排除>&{...; }'不能分配给'IntrinsicAttributes&P&{children ?: ReactNode; }'

输入'Pick,“儿童” |排除>&{...; }”不能分配给类型“ P”。

'Pick,“孩子们” |排除>&{...; }”可分配给类型“ P”的约束,但可以使用约束“ TextInputProps”的另一个子类型实例化“ P”。

如何维修?

import { View, ViewStyle, StyleProp, NativeSyntheticEvent, TextStyle, TextInputProps } from 'react-native';

type Props = {
  styleWrapper?: StyleProp<ViewStyle>;
  style?: StyleProp<TextStyle>;
  title?: string;
  value?: string;
  onFocus?: (e: NativeSyntheticEvent<any>) => void;
  onBlur?: (e: NativeSyntheticEvent<any>) => void;
  onChange?: (text: string) => void;
  onReset?: () => void;
  withReset?: boolean;
};

export const withInputWrapper = <P extends TextInputProps = TextInputProps>(
  InputComponent: React.ComponentType<P>
): React.FC<P & Props> => {
  return ({ styleWrapper, style, title, value, onFocus, onBlur, onChange, onReset, withReset = true, ...props }) => {
    const onFocusHandler = ...
    const onBlurHandler = ...

    const onChangeHandler = ...

    return (
      <View style={styleWrapper}>
        <View style={s.inputWrapper}>
          <InputComponent // <-- here
            {...props}
            onChange={onChangeHandler}
            value={value}
            style={style}
            onBlur={onBlurHandler}
            onFocus={onFocusHandler}
          />
        </View>
      </View>
    );
  };
};

2 个答案:

答案 0 :(得分:1)

这是当您达到TS可以针对具有条件和映射类型的泛型类型参数的原因时的情况之一。尽管props看起来很像P,但这对编译器来说并不明显。编译器将使用Omit键入props,该类型使用映射和条件类型从给定类型中删除一些键。因此道具将被键入为Omit<P & Props, keyof Props>。这似乎很明显P,但是TS不能遵循条件类型,只要它们仍然具有未解析的类型参数即可。这意味着,就TS而言,Omit<P & Props, keyof Props>P是不同的类型。

这里唯一的解决方案是使用类型断言:

export const withInputWrapper = <P extends TextInputProps = TextInputProps>(
  InputComponent: React.ComponentType<P>
): React.FC<P & Props> => {
  return ({ styleWrapper, style, title, value, onFocus, onBlur, onChange, onReset, withReset = true, ...props }) => {

    const onFocusHandler = () => {}
    const onBlurHandler = () => {}

      const onChangeHandler = () => {}

    return (
      <View style={styleWrapper}>
        <View>
          <InputComponent // <-- here
            {...props as P}
            onChange={onChangeHandler}
            value={value}
            style={style}
            onBlur={onBlurHandler}
            onFocus={onFocusHandler}
          />
        </View>
      </View>
    );
  };
};

Playground Link

答案 1 :(得分:1)

我必须引用一个不同的stackoverflow答案来解释您的问题:could be instantiated with a different subtype of constraint 'object'

基本上,TS无法推断您正在使用的子类型,也不允许您直接分配/假定具体类型。

这是我创建的一个沙箱,它通过不使用泛型来解决类似的问题(不是本机响应,但在这种情况下应该没有关系):https://codesandbox.io/s/serverless-tdd-91zfq

type Props = {
  styleWrapper?: any;
  style?: any;
  title?: string;
  value?: string;
  onFocus?: (e: any) => void;
  onBlur?: (e: any) => void;
  onChange?: (text: string) => void;
  onReset?: () => void;
  withReset?: boolean;
} & React.InputHTMLAttributes<HTMLInputElement>;

export const withInputWrapper = (
  InputComponent: React.ComponentType<Props>
) => ({
...

如果要使用泛型,则需要将... props强制转换为P:{...props as P}到return内部。