I am working with react-native
using typescript
. I want an onPress method with an optional boolean input parameter. And I want to pass it directly to the onPress method without creating a new arrow function
if there is no input. Like below code:
const onClose(clearMessages?: boolean) => {
// doing stuff
if (clearMessages) {
// doing extra stuff
}
}
// use it like this
<Pressable onPress={onClose}>
<Text>{'Close'}</Text>
</Pressable>
<Pressable onPress={() => onClose(true)}>
<Text>{'Clear messages'}</Text>
</Pressable>
The thing is when I call onClose directly I get the typescript error below:
Type '(clearMessage?: boolean) => (event: GestureResponderEvent) => void' is not assignable to type '(event: GestureResponderEvent) => void'. Types of parameters 'clearMessage' and 'event' are incompatible. Type 'GestureResponderEvent' is not assignable to type 'boolean'.ts(2322)
CodePudding user response:
That's an expected error! because when you don't call onClose
function yourself and pass it to pressable
, then pressable
expects the function with the below signature
((event: GestureResponderEvent) => void)
onPress
passes the parameter which has the type GestureResponderEvent
and in your onClose
function you are expecting boolean
, Hence the error
IMHO this looks clean though
onPress={() => onClose()}
If you still want it then you can achieve this by using typescript's union type, Just change your onClose
method like below
const onClose = (clearMessages?: GestureResponderEvent | boolean) => {
// doing stuff
if (typeof clearMessages === 'boolean') {
// doing extra stuff
}
};
one more(if you will pass only true
) then
const onClose = (clearMessages?: GestureResponderEvent | true) => {
// doing stuff
if (clearMessages === true) {
// doing extra stuff
}
};
CodePudding user response:
You can basically create a function which return the function you need.
const createFn = (input) => () => { console.log(input); }
const printHelloWorld = createFn("hello");
printHelloWorld();
With this in combination of useCallback()
you can create the onPress function you want in place.
Here is a full example on snack.expo.dev => https://snack.expo.dev/TPFYRuthi
It's in plain javascript due to the service, but should work in typescript just fine. Just make sure the returned function, with event
parameter, is the expected Event
type of onPress
. ✌️
export default function App() {
const createOnClose = React.useCallback(
(clearMessages?: boolean) => (event) => {
if (clearMessages) {
console.log('clearing messages');
}
console.log('onClose');
},
[]
);
return (
<View>
<Pressable onPress={createOnClose()}>
<Text>{'Close'}</Text>
</Pressable>
<Pressable onPress={createOnClose(true)}>
<Text>{'Clear messages'}</Text>
</Pressable>
</View>
);
}