Here is the example:
interface Vehicle{
mass:number
}
interface InspectorClass{
inspect(v:Vehicle):void
}
class Car implements Vehicle{
mass = 2000
wheels = 4
}
class Boat implements Vehicle{
mass = 3000
sails = 2
}
// with methods it silently fails:
class BoatInspector implements InspectorClass{
inspect(v:Boat){ // interface contract silently violated!!!
console.log(v.mass)
console.log(v.sails)
}
}
function runInspection(inspector:InspectorClass, vehicle:Vehicle){
inspector.inspect(vehicle)
}
let myCar = new Car()
let myBoatInspector = new BoatInspector()
runInspection(myBoatInspector, myCar)
// with functions it checks properly:
type InspectorFunction = (v:Vehicle) => void
const inspectCar:InspectorFunction = function(v:Car){ // TypeScript complains as it should
console.log(v.mass)
console.log(v.wheels)
}
The contract of the interface states that an inspect method in an InspectorClass instance has to be able to inspect any kind of Vehicle. Why does TypeScript let me implement a class that actually only accepts Boats without complaining? Is this a bug? Or is it by design for some reason? Or can I enable this with some flag?
The linked duplicate explains the situation. For your code above, the fix is probably to use --strictFunctionTypes
and write your method signature as a function-valued-property signature:
interface InspectorClass{
inspect: (v:Vehicle) => void
}