第二个可选参数的打字稿泛型

Nor*_*ldt 3 typescript typescript-generics

打字稿中的泛型对我来说非常先进。但我设法让这个工作

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
Run Code Online (Sandbox Code Playgroud)

但想知道是否有一种方法可以使其在trackEvent('LOGIN')没有错误和trackEvent('SUPPORT')有错误的情况下工作?

Tob*_* S. 5

我们可以使用剩余参数。如果 的类型Events[K]undefined,则剩余参数的类型计算为空元组。空元组禁止将其他参数传递给函数。[undefined?]如果您仍然希望能够提供,可以选择将其替换为undefined.

export function trackEvent<K extends keyof Events>(
  eventName: K, 
  ...[eventValues]: (Events[K] extends 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' }) // 
Run Code Online (Sandbox Code Playgroud)

操场