Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Typescript generics for 2nd optional argument

Generics in typescript is pretty advanced for me. But I managed to got this working

export type Events = {
  LOGIN: undefined
  NAVIGATION: {
    screen: string
  }
  SUPPORT: {
    communication_method: 'chat' | 'email' | 'phone'
  }
}

export function trackEvent<K extends keyof Events>(eventName: K, eventValues: Events[K]) {
  if (Platform.OS === 'web') return
  logEvent(eventName, eventValues ?? {})
}

trackEvent('LOGIN', undefined) // no TS error
// is there a way to make this work with just trackEvent('LOGIN') 

trackEvent('SUPPORT') // 👍 TS error because missing 2nd argument
trackEvent('SUPPORT', { communication_method: 'chat' }) // TS helps writing this

But wondering if there is a way to make this work with just trackEvent('LOGIN') without error and trackEvent('SUPPORT') with error?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

We can use a rest parameter. If the type of Events[K] is undefined, the type of the rest parameter evaluates to an empty tuple. The empty tuple forbids additional arguments from being passed to the function. It can be optionally replaced by [undefined?] if you still want to be able to provide undefined.

export function trackEvent<K extends keyof Events>(
  eventName: K, 
  ...[eventValues]: (Events[K] extends undefined ? [undefined?] : [Events[K]])
) {
  if (Platform.OS === 'web') return
  logEvent(eventName, eventValues ?? {})
}

trackEvent('LOGIN', undefined)
//                  ~~~~~~~~~ Expected 1 arguments, but got 2

trackEvent('SUPPORT')
//          ~~~~~~~ Expected 2 arguments, but got 1

trackEvent('LOGIN') // 👍
trackEvent('SUPPORT', { communication_method: 'chat' }) // 👍

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading