#Why is TS erroring about a simple conditional type in a function?

14 messages · Page 1 of 1 (latest)

wet yewBOT
#

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

lielmus#0

Preview:```ts
enum VehicleType {
car,
boat,
}

interface Car {
type: VehicleType.car
name: string
wheels: number
}

interface Boat {
type: VehicleType.boat
name: string
hasSails: boolean
}

function makeVehicle<
Pas
...```

mossy tapir
#

You cannot narrow generic, it's not always safe.

#

You either:

  • (Imo the better way) split up the function into makeCar and makeBoat.
  • Use mapped type if you really want to have just one function.
hasty flame
#

But I mean, I'm literally narrowing it with a discriminated union

#

Just seems superweird that the compiller doesn't allow it

#

And I mean the logic in the conditional type PassedVehicleType extends VehicleType.car ? Car exactly overlaps with the implementation if (vehicleType == VehicleType.car) return car: Car ...

mossy tapir
#

Just because vehicleType === VehicleType.car, doesn't mean PassedVehicleType has to be Car, it could still be a wider type (Car | Boat), or it could still be a narrower type (Car & { extraProperty: string }).

#

In this case the return is safe even though you can't narrow it, but it's not safe in general, and that's why it's not supported.

hasty flame
wet yewBOT
#

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

lielmus#0

Preview:```ts
enum VehicleType {
car,
boat,
}

interface Car {
type: VehicleType.car
name: string
wheels: number
}

interface Boat {
type: VehicleType.boat
name: string
hasSails: boolean
}

type VehicleTypes = {
[VehicleType.car]:
...```

mossy tapir
#

You can do something like this:

wet yewBOT
#
nonspicyburrito#0

Preview:```ts
enum VehicleType {
car,
boat,
}

interface Car {
type: VehicleType.car
name: string
wheels: number
}

interface Boat {
type: VehicleType.boat
name: string
hasSails: boolean
}

type VehicleTypes = {
[VehicleType.car]: C
...```