Discriminating Union
is a TypeScript property allowing behaviour of a type depending on an object's values.
type WaterVehicle = { isWater: true, engines: number } type RoadVehicle = { isWater?: false, wheels: number } type Vehicle = { name: string } & (WaterVehicle | RoadVehicle) const car: Vehicle = {name: "Car"} //Property 'wheels' is missing in type '{ name: string; }' but required in type 'RoadVehicle'. const boat: Vehicle = {name: "Car", isWater: true} //Property 'engines' is missing in type '{ name: string; isWater: true; }' but required in type 'WaterVehicle'
In the above example object car
doesn't require initialization of engines
field, because value isWater
was not initialized. It equals undefined
by default, which means isWater?
condition is fulfilled (it's optional). Because of that, Vehicle
type in this case requires wheels
to be declared and engines
field doesn't exist.
Same effect would occur in case of setting isWater
field value as false
.
boat
object contains isWater
field as true
. It means WaterVehicle
type is applied in this case, which causes engines
field to be required and wheels
field doesn't exist.
Discriminating field doesn't have to be a boolean - it can be any other primitive value or an enum.
type WaterVehicle = { name: "Water", engines: number } type RoadVehicle = { name: "Road", wheels: number } type Vehicle = WaterVehicle | RoadVehicle;; const car: Vehicle = {name: "Road"} // Property 'wheels' is missing in type '{ name: "Road"; }' but required in type 'RoadVehicle'. const boat: Vehicle = {name: "Water"} // Property 'engines' is missing in type '{ name: "Water"; }' but required in type 'WaterVehicle'