在声明表示所接收对象的参数类型时,是否应该手动解析从服务器接收的JSON字符串?
我在处理Http结果时使用了一个可观察的reducer函数。当参数类型在声明表示所接收对象的参数类型时,是否应该手动解析从服务器接收的JSON字符串?,json,angular,typescript,ngrx,ngrx-effects,Json,Angular,Typescript,Ngrx,Ngrx Effects,我在处理Http结果时使用了一个可观察的reducer函数。当参数类型jwt设置为{id:string,auth\u token:string,expires\u in}时,jwt参数变成了string。我以为TypeScript会自动解析。我必须自己做JSON.parse(JSON.stringify(jwt))吗 .mergeMap((jwt: { id: string, auth_token: string, expires_in }) => {}) 如果使用Http从HttpMo
jwt
设置为{id:string,auth\u token:string,expires\u in}
时,jwt
参数变成了string
。我以为TypeScript会自动解析。我必须自己做JSON.parse(JSON.stringify(jwt))
吗
.mergeMap((jwt: { id: string, auth_token: string, expires_in }) => {})
如果使用Http
从HttpModule
@angular/Http
检索jwt(JSON)对象,则必须将其解析为JSON
e、 g:
如果使用HttpClientModule
@angular/common/http
(angular>4.3.x)中的HttpClient
,则无需解析接收到的数据,因为已经完成了解析
import { HttpClient } from '@angular/common/http';
....
constructor(
private http: HttpClient
...
) {}
this.http.get<any>(url)
.subscribe((jwt: any) => {
//you got jwt in JSON format
})
从'@angular/common/http'导入{HttpClient};
....
建造师(
私有http:HttpClient
...
) {}
this.http.get类型检查外部代码
TypeScript源代码与运行时执行的JavaScript输出之间没有关系。只有在编译类型与运行时类型匹配时,TypeScript才能有效捕获编译时错误
通常,这不是问题。但在调用外部代码的场景中(即从服务器获取数据的AJAX调用),无法保证响应将是您期望的类型。因此,在这些情况下,您必须谨慎
你的具体例子
我怀疑您的代码中有一个变量jwt
,类型为any
,您刚刚将该类型分配给{id:string,auth\u token:string,expires\u in}
,而实际上,jwt
就javascript而言是字符串类型
在本例中,您已经找到了解决方案,JSON.parse(str)
。这会将json字符串转换为javascript对象
现在您有了一个对象,可以使用duck类型推断运行时类型,并在编译时通过让typescript知道该类型
解决方案
游乐场
尝试在上运行该代码,以查看它在运行时如何检查对象
import { HttpClient } from '@angular/common/http';
....
constructor(
private http: HttpClient
...
) {}
this.http.get<any>(url)
.subscribe((jwt: any) => {
//you got jwt in JSON format
})
function isDate(obj: any): obj is Date {
return typeof obj === 'object' && 'toISOString' in obj;
}
function isString(obj: any): obj is string {
return typeof obj === 'string';
}
interface JWT {
id: string;
auth_token: string;
expires_in: Date;
}
function isJwt(obj: any): obj is JWT {
const o = obj as JWT;
return o !== null
&& typeof o === 'object'
&& isString(o.id)
&& isString(o.auth_token)
&& isDate(o.expires_in);
}
function print(jwt: any) {
if (typeof jwt === 'string') {
try {
jwt = JSON.parse(jwt);
} catch (e) {
console.error(`String is not JSON: ${jwt}`);
}
}
if (isJwt(jwt)) {
console.log(`Found jwt: ${jwt.id} ${jwt.auth_token} ${jwt.expires_in}`);
} else {
console.error(`Object is not of type jwt: ${jwt}`);
}
}
print(42);
print('failing');
print(null);
print(undefined);
print({});
print({ id: 'id01', auth_token: 'token01', expires_in: new Date(2018, 11, 25) });