#2nd parameter of function depends on 1st

53 messages · Page 1 of 1 (latest)

odd edgeBOT
#

@fringe wolf Here's a shortened URL of your playground link! You can remove the full link from your message.

bhavyacodes#0

Preview:```ts
type AppleOptions = {
iron: number
}

type OrangeOptions = {
vitaminC: number
}

function sayHello(
fruit: "apple" | "orange",
fruitOptions: any
) {
switch (fruit) {
case "apple":
console.log(apple has ${fruitOptions} iron)
break
case "orange":
console.l
...```

fringe wolf
#

!ts

odd edgeBOT
#
type AppleOptions = {
  iron: number
}

type OrangeOptions = {
  vitaminC: number
}

function sayHello(fruit: 'apple' | 'orange', fruitOptions: any){
  switch(fruit){
    case 'apple':
      console.log(`apple has ${fruitOptions} iron`)
      break
    case 'orange':
      console.log(`Orange has ${fruitOptions.vitaminC} vitamin C`)
  }
}```
sleek shoal
#

is fruitOptions supposed to be the number or an object?

fringe wolf
#

yes its a mistake, im unable to edit

#
type AppleOptions = {
  iron: number
}

type OrangeOptions = {
  vitaminC: number
}

function sayHello(fruit: 'apple' | 'orange', fruitOptions: any){
  switch(fruit){
    case 'apple':
      console.log(`apple has ${fruitOptions.iron} iron`)
      break
    case 'orange':
      console.log(`Orange has ${fruitOptions.vitaminC} vitamin C`)
  }
}
sleek shoal
#

this is kinda hard to do safely

#

you could use a generic function, but then the generic could be a union.

#

it'd be easier if you could form the arguments as a discriminated union

fringe wolf
#

earlier I tried using something like

sayHello(...args: ['apple' , {iron: number}] | ['orange' , {vitaminC: number}]){}
#

but that didn't work for some reason

sleek shoal
#

oh, right, that is a discriminated union.

nocturne lion
#

Do it with spread parameters + union.

odd edgeBOT
#
nonspicyburrito#0

Preview:```ts
type AppleOptions = {
iron: number
}

type OrangeOptions = {
vitaminC: number
}

function sayHello(
...[fruit, options]:
| [fruit: "apple", options: AppleOptions]
| [fruit: "orange", options: OrangeOptions]
) {
swit
...```

sleek shoal
fringe wolf
#

!close

#

!open

#

ok it works, but is there a better way, thing is im building a library that has to be used by others, and the error looks like this

#

if there was a better way using generic please help

sleek shoal
#

what about an object?

fringe wolf
#

hmmmm yeah but this what my boss wants

#

and i like I would also like it this way, first param to be a string and 2nd depending on the first arg

#

possible to do something like this?

#
  async dial<ChainType extends ChainNetwork>(
    chain: ChainType,
    options: ChainType === 'moi' ? MoiOptions : EthereumOptions,
  ) {}
#

type ChainNetwork = 'moi' | 'ethereum';

sleek shoal
#

conditionals in signatures are almost never what you need

fringe wolf
#

I mean I will be adding the runtime check also manually

sleek shoal
#

also, you could pass ChainNetwork and then pass "moi" and EtheriumOptions

fringe wolf
#

its just for types

fringe wolf
nocturne lion
#

You can use generic for this, but inside the implementation it would get very ugly.

#

DU is generally the way to go.

fringe wolf
#

pl0x

#

😽

odd edgeBOT
#
nonspicyburrito#0

Preview:```ts
type AppleOptions = {
iron: number
}

type OrangeOptions = {
vitaminC: number
}

type ParameterMap = {
apple: AppleOptions
orange: OrangeOptions
}

function sayHello<T extends keyof ParameterMap>(
fruit: T,
options: P
...```

nocturne lion
#

You have no way to fix the error inside your implemenetation and just have to cast.

#

And it's also unsafe, people can do:

sayHello<'apple' | 'orange'>('apple', { vitaminC: 42 })

And it will explode at runtime.

fringe wolf
#

I think I know what to do

#

first param is string

#

I can make an object with those strings as keys

#

and do some keyof magic with generics

nocturne lion
fringe wolf
#

ohhh lol

nocturne lion
#

But also read my comments following it.

#

It's not a good solution.

fringe wolf
#

okay, i'll try a little more digging

#

Thanks!