为什么 TypeScript 没有缩小这个类型保护中的 any-type 的范围?

Ale*_*lex 4 typescript

下面的例子让我困惑:

class MyClass
{
    public MyProp = "";
}

var object: any = null;

if (object instanceof MyClass)
    console.log(object.MyProp, object.NonExistant); // <-- No error, no intellisense
Run Code Online (Sandbox Code Playgroud)

为什么类型保护没有在检查的上下文中给我正确的类型?

Ale*_*lex 5

用户定义的类型保护instanceof类型保护不会缩小属于any(包括联合交叉类型 with any) 的类型。

唯一可以缩小any类型保护范围的是使用typeof检查和检查原语string, bool, 和number

var something: any;
if (typeof something === "string")
{
    something.NonExistant(); // <- Error, does not exist on `string`
    something.substr(0, 10); // <- Ok
}
Run Code Online (Sandbox Code Playgroud)

其他通用的typeof值functionobject并且undefined,不缩小any,如果一个会尝试使用它们像上面的例子。

还有一个未解决的问题可以缩小any到用户定义的类型保护中的原语,这是 TS 2.0 的里程碑。

这是一个有意识的设计决定,而不是一个错误

主要动机似乎是对类型进行类型保护通常会缩小可能的类型,并且我们可以访问更多可以确定存在于已检查上下文中的属性。但是在对 special 进行类型保护的情况下any,我们已经可以访问可能存在的所有成员,因此any像您在示例中所期望的那样对 an 进行类型保护实际上会限制我们。

另一个动机似乎是,如果 TypeScript像其他类型一样缩小,就会有太多糟糕的代码会破坏any

解决方法

如果您有一个变量可以是任意类的实例,请使用类型Object而不是any类型保护将按预期工作。