Angular4 HttpClient 类型检查问题

Angular4 HttpClient TypeCheck issue

听说新的Angular的HttpClient可以进行TypeChecking,据此我写了下面的代码

post(path: string, body: Object = {}): Observable<ValorTest> {
return this.http.post<ValorTest>(path, JSON.stringify(body))
  .map((data: ValorTest) => {
    console.log(typeof data); // Why console displays 'data' as object instead of ValorTest?
    console.log(data instanceof ValorTest); // outputs: false
    console.log(data); // outputs (no type displayed in Chrome's console): {codigo: "INF00001", estado: "Success"}
  })
  .pipe(catchError(this.formatErrors));

}

我收到了与我的模型 class (ValorTest) 匹配的 JSON。

问题:为什么 console.log 将数据类型显示为对象而不是 ValorTest?

typeof 调用只会发出 JS 的内置类型,您可能想要做的是检查 instanceof,它会告诉您返回值是否与您的自定义类型匹配!

如果你只是做类型检查/断言,你可以使用 instanceof。如果你真的需要打印class的名字,你可以试试data.constructor.name:

class TestClass {}

var instance  = new TestClass();

console.log(typeof instance);
// Expected output: "object"

console.log(instance.constructor.name);
// Expected output: "TestClass"

if (instance instanceof TestClass) {
    console.log("instance is TestClass");
}
// Expected output: "instance is TestClass"

至于原因:typeof 仅适用于 JavaScript 的内置数据类型,例如字符串、布尔值、对象等。如果您 look at the way TypeScript transpiles 到 JavaScript,您可以理解为什么在运行时 JavaScript 只知道您的实例是 "object".

已更新

这仅适用于使用新的 class() 构造函数创建的实例。 HttpClient 实际上并没有在这里为您创建 class 的实例——它基本上只是允许您(出于开发目的)使用 TypeScript 指定您希望接收的数据类型 在响应中。据我所知,HttpClient 没有做任何事情来确保(在运行时)响应数据 实际上满足 这些期望。如果您需要在运行时进行强类型检查,您可能需要编写自己的类型保护函数。

所以如果你有这样的class:

class TestClass {
    prop: string;
    constructor() { }
    method(): void {}
}

你可以像这样写一个类型保护:

function isTestClass(obj: TestClass | object): obj is TestClass {
    // add whatever type checking logic you need here
    return (<TestClass>obj).method !== undefined && 
           (<TestClass>obj).prop !== undefined; 
}

并在运行时检查您的数据:

var obj_a = { prop: "" },
    obj_b = { prop: "", method: null };

console.log(isTestClass(obj_a));
// Expected output: false

console.log(isTestClass(obj_b));
// Expected output: true

我可能会将类型保护函数设为我 class 的静态方法。

此外,顺便说一句,您可能会考虑为响应数据使用一个接口而不是 class——主要是因为它可能有助于激发您的直觉,即您收到的数据可能会也可能不会有你期望的实现。

有关 user-defined 类型守卫的更多信息,请访问: https://www.typescriptlang.org/docs/handbook/advanced-types.html

与HttpClient无关,所有typescript代码和类型都转换为javascript浏览器可以编译,然后javascript使用对象处理它们,所以在控制台中它只知道对象。