在声明表示所接收对象的参数类型时,是否应该手动解析从服务器接收的JSON字符串?

在声明表示所接收对象的参数类型时,是否应该手动解析从服务器接收的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

我在处理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
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) });