#How to call an overloaded function inside of a generic function?

44 messages · Page 1 of 1 (latest)

void lynxBOT
#
zamiel#0

Preview:```ts
enum FruitType {
Apple,
Banana,
}

enum AppleType {
Value1,
Value2,
}

enum BananaType {
Value1,
Value2,
}

function getFruit(
fruitType: FruitType.Apple,
appleType: AppleType
): string
function getFruit(
fruitType: FruitType.Banana,
bananaType: BananaType
): string
...```

solemn lily
#

This is a short example that illustrates what I mean.

coral coyote
#

i have no idea what you mean

#

getFruitGeneric(FruitType.Apple, BananaType.Value1) is valid there

#

are you trying to make them correspond, or what exactly?

solemn lily
#

There's a type error in the playground before we even get to typing out an invocation.

#

How to solve the type error?

coral coyote
#

what do you want it to do

coral coyote
#

do you want to disallow or handle that case

solemn lily
#

Well, I'll show you what I mean without a generic function.

void lynxBOT
#
zamiel#0

Preview:```ts
enum FruitType {
Apple,
Banana,
}

enum AppleType {
Value1,
Value2,
}

enum BananaType {
Value1,
Value2,
}

function getFruit(
fruitType: FruitType.Apple,
appleType: AppleType
): string
function getFruit(
fruitType: FruitType.Banana,
bananaType: BananaType
): string
...```

solemn lily
#

Here, we get some type errors, because TypeScript isn't smart enough to type-narrow the things into the overload.

coral coyote
#

no?

solemn lily
#

Or rather, because it is possible to pass the wrong type of arg.

coral coyote
#

arg isn't related to fruitType

#

yes

solemn lily
#

Right.

coral coyote
solemn lily
#

So we need to establish a relationship between the two arguments, which is why we probably need to write a generic function.

coral coyote
#

uh

#

that's what overloads do

#

you already have this function, getFruit

solemn lily
#

You could imagine that getFruit has 100 overloads.

coral coyote
#

so you mean to say, you want to replace getFruit

#

is that it?

solemn lily
#

If I want to have getFruit but with some additional functionality, is there a way to avoid copy pasting the 100 overloads into the getFruitWithExtra function?

coral coyote
#

i see

#

since Parameters doesn't work over all the signatures, i think this is closest you could get

void lynxBOT
#
that_guy977#0

Preview:ts ... const getFruit_: typeof getFruit = ( fruitType: FruitType, subtype: AppleType | BananaType ) => { getFruit(fruitType, subtype) } ...

coral coyote
#

needs casts though.

#

also it is quite unsafe

#

since you can't go through all the overloads to get an accurate typing

solemn lily
#

Isn't it possible to define a relationship between arg1 and arg2 with a generic parameter such that TypeScript will understand the correct relationship and use the appropriate overload?

coral coyote
#

you could always use a union on the generic, which is a problem overloads solve

#

unless you use a validator type maybe, but that'll get quite messy

solemn lily
#

But the union type doesn't work either; please see the code snippet in my original question.

coral coyote
#

that's the problem

#

you can use a union for the generic at the call site, so it's not the behavior overloads give

solemn lily
#

Oh, I found an alternate solution is to make a non-specific overload on getFruit.

#

Is there a way to validate that a function has an overload for every constituent of a union?

#

The reason I ask is because by adding the non-specific overload, it makes the function now unsafe to use if a new fruit is added.

coral coyote
#

don't think so

#

the function would be unsafe without a new fruit since a misalign would fall to the non-specific overload