承诺不返回有效的类实例

时间:2017-09-17 20:34:24

标签: angular typescript

我刚刚开始学习Typescript,而且我已经迷失了对C#开发人员来说听起来很奇怪的事情。

摘要: Promise<WsIdSessionResponse>返回的变量具有相同的WsIdSessionResponse类字段,但它不是有效的WsIdSessionResponse实例。

长篇故事
我有这样的服务(我已经省略了对问题无用的东西)消耗了一个非我写的JSON Web服务:

export class WsIdSessionService {
    constructor(private http: HttpClient) { }

    doLoginAsync(user: string, pwd: string): Promise<WsIdSessionResponse> {
        let params = new HttpParams();
        params = params.append('username', user);
        params = params.append('password', pwd);
        return this.http.get<WsIdSessionResponse>(this.apiUrl, {params: params})
            .toPromise());
    };

WsIdSessionResponse 类就像这样

export class WsIdSessionResponse {
    public status: number;
    public username: string;

    public isOk(): boolean {
        return this.status == 1;
    }
}

当我从WsIdSessionService检索数据时出现问题:

var idSvc = this.wsIdSession.doLoginAsync(user, pwd);
var t = idSvc.then(info => {
    if (t.isOk()) {
      // Do something here
    }
}

当我执行t.isOk()时,我收到错误,告诉我isOk()不是函数!
什么?!?不是功能?是的,我在班上有这个功能!

浪费了大量时间后,我终于考虑尝试这段代码了

var idSvc = this.wsIdSession.doLoginAsync(user, pwd);
var t = idSvc.then(info => {
    console.warn(`info is valid: ${info instanceof WsIdSessionResponse}`);
}

这里我得到一个false:所以返回的变量具有我需要的类的相同字段,但它不是类的真实实例,而且原因是{{1功能无效!
但这怎么可能呢?我的意思是,isOk()应该返回http.get<WsIdSessionResponse>的有效实例或最终出错...我错了吗?

只是提供完整的信息:WsIdSessionResponse从返回普通JSON字符串的网址中获取数据。

这是预期的行为还是我做错了什么?

1 个答案:

答案 0 :(得分:1)

<WsIdSessionResponse>不会使对象成为WsIdSessionResponse的实例。它欺骗打字系统认为它是一个实例并抑制类型错误。 TypeScript是安全类型的JavaScript,编译时只是JavaScript。

除非使用WsIdSessionResponse明确创建new的实例,否则该对象将保留Object,而不使用isOk方法。

它的工作方式是:

interface IWsIdSessionResponse {
    status: number;
    username: string;
}

class WsIdSessionResponse implements IWsIdSessionResponse {
    public status: number;
    public username: string;

    public isOk(): boolean {
        return this.status == 1;
    }
}

...

doLoginAsync(user: string, pwd: string): Promise<WsIdSessionResponse> {
        ...
        return this.http.get<IWsIdSessionResponse>(this.apiUrl, {params: params})
            .map(plainResponseObj => Object.assign(new WsIdSessionResponse, plainResponseObj))
            .toPromise());
    };