Home > Software engineering >  How to declare onPress function with optional input parameter in react native using typescirpt
How to declare onPress function with optional input parameter in react native using typescirpt

Time:12-17

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>
  );
}
  • Related