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使用对象处理它们,所以在控制台中它只知道对象。
听说新的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使用对象处理它们,所以在控制台中它只知道对象。