enum Unit {
Kilometer,
Meter,
}
interface Measurement {
distanceUnit: Unit
distance: number
}
interface MetersMeasurement {
distanceUnit: Unit.Meter
}
function someCalculation(item: MetersMeasurement){
return;
}
function main(){
const item : Measurement = {
distance: 100,
distanceUnit: Unit.Meter
}
if(item.distanceUnit !== Unit.Meter) return;
someCalculation(item)
// ^^^^ Types of property 'distanceUnit' are incompatible.
// Type 'Unit' is not assignable to type 'Unit.Meter'.
}
If
MetersMeasurementandMeasurementhad the same fields, we could use a type predicate to narrow it down. But my problem requires thatMetersMeasurementwill only have a subset of the fields ofMeasurement. Therefore a type predicate wouldn't work [playground].We could also change the type of
distanceUnitin the interfaceMetersMeasurementtoUnit. And then move theifcheck for meters insidesomeCalculationfunction. But let's also say I don't want to do that. I don't want to give the function this responsibility.We could create a new object of type
MetersMeasurementbased on the original object and then pass that tosomeCalculation()instead. But this feels like a workaround (and extra code) because we couldn't narrow down the type [playground].
Is there a way to properly narrow down the type without breaking the rules? (no any or casting)