Typescript不会检测类型错误

Man*_*ner 9 typescript

我有以下代码片段:

文件router-data.ts#L46

...
const fd = FroniusMeter.getInstance(req.query.address ? req.query.address : 1);
....
Run Code Online (Sandbox Code Playgroud)

该方法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;
}
Run Code Online (Sandbox Code Playgroud)

在没有警告或错误(tsconfig.json)的情况下编译源代码,但执行会抛出异常TypeError: id.startsWith is not a function.

原因很清楚,调用getInstance()使用数字作为参数,但该方法是为字符串编写的参数.因此id.startsWith(...抛出错误.

我的问题,为什么打字稿不会打印出一些警告或错误?

Avi*_*dad 7

原因很简单,req.query定义为any.所以req.query.address也被定义为任何.

我们来看看这段代码:

let f: TypeA;
let g: TypeB;
let bool: boolean;
let x = bool ? g : f;
Run Code Online (Sandbox Code Playgroud)

Typescript将推断出x的类型TypeA | TypeB.

因此,表达式的类型在req.query.address ? req.query.address : 1技术上是合适的any | number,但这只是any.

在typescript 3.0中unknown,应该添加一个名为的新类型,这应该可以解决这个问题.


Tit*_*mir 4

这个通过的原因很简单,来自于其类型req.queryany。由于这是any任何属性访问也将是类型anyreq.query.address类型也是如此any

如果条件表达式的两个分支具有不同的类型,则条件表达式类型将计算为两个分支的并集

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

然而,在联合中any总是会吃掉任何其他类型,因此任一分支具有 an 的条件any将被键入为any

let y: any;
let x = Math.random() > 0.5 ? y : 0; // x is any
Run Code Online (Sandbox Code Playgroud)

因此,在您的通话中req.query.address ? req.query.address : 1, 是 类型any,因此可分配给string.

这就是为什么any应该像瘟疫一样避免,尤其是图书馆作者。