skip to Main Content

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)

2

Answers


  1. 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
      }
    };
    
    Login or Signup to reply.
  2. 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>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search