It is HOC, I have follow errors:
Type 'Pick, "children" | Exclude> & { ...; }' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'
Type 'Pick, "children" | Exclude> & { ...; }' is not assignable to type 'P'.
'Pick, "children" | Exclude> & { ...; }' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'TextInputProps'.
How repair it?
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>
);
};
};
This is one of those cases when you have reached the limit of what TS can reason about generic type parameters with conditional and mapped types. While props
might seem obviously P
, this is not obvious to the compiler. The compiler will use Omit
to type props
which uses mapped and conditional types to remove some keys from a given type. So props will be typed as Omit<P & Props, keyof Props>
. This might seem obviously P
, but TS can't follow conditional types as long as they still have unresolved type parameters. This means, as far as TS is concerned Omit<P & Props, keyof Props>
and P
are different types.
The only solution here is to use a type assertion:
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
I have to quote a different stackoverflow answer explaining your problem: could be instantiated with a different subtype of constraint 'object'
Basically TS cannot infer which subtype you are using and doesn't let you assign/assume a concrete type directly.
Here's a sandbox I created which fixes a similar issue by not using generics (it's not react-native but shouldn't matter in this case): 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>
) => ({
...
If you want to use generics you need to cast ...props to P: {...props as P}
inside return.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With