Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript make the second parameter type depends on the first parameter type

enum Channel {
  GITHUG = 'github',
  GITLAB = 'gitlab',
}

interface Github {}

interface Gitlab {}

function foo (a, b) {}

The first parameter a is an enum (Channel) value

If parameter a is github, then the type of b is GitHub

If parameter a is gitlab, then the type of b is Gitlab

How to define the type of function foo?

like image 759
loveyunk Avatar asked Oct 22 '25 06:10

loveyunk


2 Answers

Here you have some alternative ways:

enum Channel {
  GITHUB = 'github',
  GITLAB = 'gitlab',
}

interface Github {
  type: 'Github'
}

interface Gitlab {
  type: 'Gitlab'
}

/**
 * First approach
 */
type Params = [Channel.GITHUB, Github] | [Channel.GITLAB, Gitlab]

function foo(...args: Params) {
  if (args[0] === Channel.GITHUB) {
    const x = args[1] // Github
  }
}


type Overloading =
  & ((a: Channel.GITHUB, b: Github) => void)
  & ((a: Channel.GITLAB, b: Gitlab) => void)


/**
 * Second approach
 */

const foo2: Overloading = (a: Channel, b: Github | Gitlab) => null as any

const result = foo2(Channel.GITHUB, { type: 'Github' }) // ok


/**
 * Third approach
 */
function foo3(a: Channel.GITLAB, b: Gitlab): void
function foo3(a: Channel.GITHUB, b: Github): void
function foo3(a: Channel, b: Github | Gitlab) {

}
foo3(Channel.GITLAB, { type: 'Gitlab' }) // ok

Playground

like image 68
captain-yossarian Avatar answered Oct 24 '25 21:10

captain-yossarian


Use conditional types technique. Look at example below or go to online playground in order to test in action (thanks for help to Joonas)

enum Channel {
  GITHUG = 'github',
  GITLAB = 'gitlab',
}

interface Github {
  _foo: number
}

interface Gitlab {
  _bar: number
}

type ParamType<C> = C extends Channel.GITHUG ? Github : Gitlab;
function foo<C extends Channel>(a: C, b: ParamType<C>): void {}

foo(Channel.GITLAB, { _foo: 1 }); // error
foo(Channel.GITLAB, { _bar: 1 }); // success

enter image description here


Please, let me know if it works or not )

like image 28
Kas Elvirov Avatar answered Oct 24 '25 21:10

Kas Elvirov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!