我有以下代码段:
...
const fd = FroniusMeter.getInstance(req.query.address ? req.query.address : 1);
....
方法getInstance()
在文件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;
}
在没有警告或错误(tsconfig.json)的情况下编译了源代码,但是执行时会抛出异常TypeError: id.startsWith is not a function
。
原因很清楚,getInstance()
的调用使用数字作为参数,但是该方法是为字符串编写的。因此id.startsWith(...
会引发错误。
我的问题是,打字稿为什么没有打印出一些警告或错误?
答案 0 :(得分:7)
原因很简单,req.query
is defined as any
。因此req.query.address
也被定义为any。
让我们使用以下代码:
let f: TypeA;
let g: TypeB;
let bool: boolean;
let x = bool ? g : f;
Typescript将推断x的类型为TypeA | TypeB
。
因此,表达式req.query.address ? req.query.address : 1
的类型从技术上讲是any | number
,但这只是any
。
In typescript 3.0 a new type called unknown
is supposed to be added,应该可以解决这个问题。
答案 1 :(得分:4)
通过的原因非常简单,并且来自req.query
类型的any
。由于这是any
,因此任何属性访问都将是any
类型。因此req.query.address
的类型为any
。
如果条件表达式条件表达式的两个分支具有不同的类型,则条件表达式类型的计算结果为两者的并集
let x = Math.random() > 0.5 ? "A" : 0; // x is string | number
但是在联合中,any
总是会吃掉其他任何类型,因此其中一个分支具有any
的条件将被键入为any
let y: any;
let x = Math.random() > 0.5 ? y : 0; // x is any
因此,在您的通话中,req.query.address ? req.query.address : 1
的类型为any
,因此可以分配给string
。
这就是为什么any
应当像瘟疫一样被避免,尤其是图书馆作家。