Skip to content

Impossible to transform from a discriminated union to another using a different discriminant field #35140

Closed
@OzTK

Description

@OzTK

It does not seem to be possible to change the discriminant from one property to another and have that recognised as the proper type.

TypeScript Version: 3.8.0-dev.20191116

Search Terms: discriminated union, discriminant, kind, type

Code

interface Car {
  kind: 'car'
  trunkSize: number
}

interface Bike {
  kind: 'bike'
  handlebarColor: string
}

interface ApiCar {
  type: 'car'
  trunkSize: number
}

interface ApiBike {
  type: 'bike'
  handlebarColor: string
}

type Vehicle = Car | Bike

type ApiVehicle = ApiCar | ApiBike

const unknown = {
  type: 'car',
  trunkSize: 5
}

function makeVehicle(vehicle: ApiVehicle): Vehicle {
  return { ...vehicle, kind: vehicle.type }
}

Expected behavior:
Object returned by makeVehicle should successfully be interepreted by the compiler as a Vehicle

Actual behavior:
Does not compile with the following error:

Type '{ kind: "car" | "bike"; type: "car"; trunkSize: number; } | { kind: "car" | "bike"; type: "bike"; handlebarColor: string; }' is not assignable to type 'Vehicle'.
  Type '{ kind: "car" | "bike"; type: "car"; trunkSize: number; }' is not assignable to type 'Vehicle'.
    Type '{ kind: "car" | "bike"; type: "car"; trunkSize: number; }' is not assignable to type 'Car'.
      Types of property 'kind' are incompatible.
        Type '"car" | "bike"' is not assignable to type '"car"'.
          Type '"bike"' is not assignable to type '"car"'.(2322)

Playground Link:
http://www.typescriptlang.org/play/?ts=3.8.0-dev.20191115&ssl=31&ssc=36&pln=30&pc=53#code/JYOwLgpgTgZghgYwgAgMJysg3gKGcga1ABMAuZAcgQwr2TCgFcQCBlYALwnJEYFsARtBwBfHDlCRYiFACFgBFLnxEQZSgIURa+ABZw1AGwgCMqAPaHzUcgGcGoAOajxk6PCTIAggAdg6TGV6AE8fbkpqKB16JhZ2Lh5+ISgXCXB3GW8-eUVsOjBQ8IpNRWj9IxMzS2s7BxBnMRwCsOQANQhdYARjZABeNAxkAB8AApyIcWaUX2B2zu6UfpmA4azgcfEEcxB7ZGYCEHMAdxA+vPwp8ioaABp82LZOcIBWVJhmBDBgbeQ+OEU5l1jAAKABuHSB4RmgIWAEpyDCekEoBAwIwoKcsMgAHS48HzYw3Qgkcj4yHYqbIMQiIA

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions