Typescript does not detect type error

  • A+
Category:Languages

I have the following code snippets:

File router-data.ts#L46

... const fd = FroniusMeter.getInstance(req.query.address ? req.query.address : 1); .... 

The method getInstance() is defined in file fronius-meter.ts#L51

public static getInstance (id: string): FroniusMeter {     if (id.startsWith('/dev')) {         debug.info('...');     }     let rv = ModbusDevice.getInstance(id);     if (!rv) {         rv = ModbusDevice.instances.find( (d) => (d instanceof FroniusMeter) && (d.address === +id) );     }     return rv instanceof FroniusMeter ? rv : null; } 

The sources are transpiled without warning or error (tsconfig.json), but executing throws an exception TypeError: id.startsWith is not a function.

The reason is clear, the call of getInstance() uses a number as parameter, but the method is written for a string as parameter. Therefore id.startsWith(... throws an error.

My question, why did typescript transpilation not print out some warning or error?

 


The reason this passes is very simple, and comes from the type of req.query which is any. Since this is any any property access will also be of type any. So req.query.address is of type any.

If conditional the two branches of a conditional expression have different types the conditional expression type will evaluate to the union of the two

let x = Math.random() > 0.5 ? "A" : 0; // x is string | number 

However in a union any will always eat up any other types so a conditional in which either branch has an any will be typed as any

let y: any; let x = Math.random() > 0.5 ? y : 0; // x is any 

So in your call req.query.address ? req.query.address : 1 is of type any and thus assignable to string.

And this is why any should be avoided like the plague especially by library writers.

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: