In TypeScript, when you use a union type with |
operator, the properties of the individual types in the union become optional in the resulting union type. This means that you can access optional properties on the union type, but TypeScript will also allow you to access properties that are common to all the types in the union without checking for their existence.
Here's an example to illustrate this behavior:
typescriptinterface Car {
brand: string;
model: string;
}
interface Bike {
type: string;
}
type Vehicle = Car | Bike;
function printVehicleInfo(vehicle: Vehicle) {
// Accessing properties that are common to all types in the union
console.log(vehicle.brand);
// TypeScript allows accessing 'brand' and 'model' properties directly without checking.
// It assumes they exist on all types in the union, but in runtime it will be checked.
// Accessing properties specific to a type in the union
if ('type' in vehicle) {
console.log(vehicle.type);
// TypeScript allows accessing 'type' property because it's part of the 'Bike' type
// But TypeScript will not allow accessing 'type' property on 'Car' type without checking.
} else {
console.log(vehicle.model);
// TypeScript allows accessing 'model' property because it's part of the 'Car' type
// But TypeScript will not allow accessing 'model' property on 'Bike' type without checking.
}
}
const myCar: Car = { brand: 'Toyota', model: 'Camry' };
printVehicleInfo(myCar); // Output: Toyota
const myBike: Bike = { type: 'Mountain' };
printVehicleInfo(myBike); // Output: Mountain
In the example above, we have a union type Vehicle
that consists of Car
and Bike
. Both Car
and Bike
have their own specific properties, and when combined in the union, all properties become optional.
When accessing properties common to all types in the union (e.g., brand
and model
), TypeScript assumes they exist, but the existence will be checked during runtime.
When accessing properties specific to a type in the union (e.g., type
), TypeScript will require a type check using the in
operator or custom type guards before accessing the property to ensure it's present on the particular type.
Remember that optional properties should be used carefully, as you need to account for possible undefined values when accessing them. Type guards or conditional checks can be used to safely access optional properties based on the type in the union.