Introduction to problem
I am struggling to develop strong typing for a particular function written in TypeScript...
For illustrative purposes, lets say I work at the Department of Motor Vehicles and have a function registerVehicles
that can accept registration details for many vehicles organised by name, and returns the license plates for each vehicle.
interface RegistrationDetails {
transmission?: 'manual' | 'automatic';
wheelCount?: number;
horsePower?: number;
}
const licensePlates = registerVehicles({
sportsCar: {
transmission: 'manual',
wheelCount: 4,
horsePower: 762
},
motorBike: {
transmission: 'manual',
wheelCount: 2
},
hoverBoard: {
// All registration details are optional
}
});
The function returns an object with the names of each vehicle and their newly registered license plates:
expect(licensePlates).to.eql({
sportsCar: 'ABCD-1234',
motorBike: 'SPDY-5678',
hoverBoard: 'BTTF-2'
});
The function exists and works perfectly, the problem is getting it strongly typed.
The solution must meet the following criteria:
The variable
licensePlates
should be implicitly typed from the result of the function.Trying to pass a registration detail that doesn't exist should error at compile time.
registerVehicles({ car: { cowPower: 500 // <-- Spelling mistake, should be horsePower } })
Trying to access the license plate of a vehicle you didn't register should error at compile time:
const licensePlates = registerVehicles({ ferrari: { horsePower: 562 } }); alert(licensePlates.furrari); // <-- Spelling mistake, should be ferrari
TypeScript should know each license plate is a string at compile-time
const licensePlates = registerVehicles({ ferrari: {} }); alert(licensePlates.ferrari * 5); // <-- Error, you can't multiple a string
I've gotten close, but every solution I try ultimately fails to meet at least one of the above requirements. Help me Stack Overflow community, you're my only hope!