TypeScript错误TS2339,但属性确实存在

问题描述:

当我使用gulp编译下面的TypeScript代码时,我得到:错误TS2339:属性'accessToken'在类型'Response'上不存在。 Visual Studio 2015中的ErrorList窗口报告data.accessTokendata.expiryDate的错误。当我注释引用变量data的两行时,代码将运行,调试程序显示data不是“响应”类型,而实际上包含属性data.accessTokendata.expiryDate。在Visual Studio中,当我将鼠标悬停在变量data上时,工具提示正确报告data的类型为anyTypeScript错误TS2339,但属性确实存在

为什么TypeScript无法正确传输,我该如何解决问题?为什么TypeScript认为data的类型是Response而不是any? 我正在使用TypeScript 2.1.4。 http.fetch使用奥里利亚获取客户documented here

/// <reference path="../typings/index.d.ts" /> 
import 'fetch'; 
import {HttpClient, json} from 'aurelia-fetch-client'; 
import {inject} from 'aurelia-framework'; 
import {BearerToken} from './common/bearer-token'; 
export class ApiToken 
{ 
... 
    public refreshToken(): Promise<BearerToken> 
    { 
     let token: BearerToken = new BearerToken(); 
     token.accessToken = "no_data"; 
     token.expiryDate = Date.now(); 

     return this.http.fetch('/Account/getToken') 
      .then(response => response.json()) 
      .then(data => 
      {     
       console.log('ApiToken.refreshToken returned data: ' + data); 

       // The next two lines cause build errors. 
       // When commented out the code runs and the debugger shows that 
       // data.accessToken and data.expiryDate do exist on data. 
       token.accessToken = data.accessToken; 
       token.expiryDate = data.expiryDate;   

       return token; 
      }) 
      .then((t) => { return this.saveToken(t) }); 
    } 
... 
} 

这里是我的tsconfig.json文件:

{ 
    "compileOnSave": false, 
    "compilerOptions": { 
    "rootDir": "src", 
    "outDir": "dist", 
    "sourceMap": true, 
    "target": "es5", 
    "module": "amd", 
    "declaration": false, 
    "noImplicitAny": false, 
    "removeComments": true, 
    "emitDecoratorMetadata": true, 
    "experimentalDecorators": true, 
    "moduleResolution": "node", 
    "lib": ["es2015", "dom"], 
    "baseUrl": "./", 
    "paths": { 
     "src/*": ["src/*"] 
    } 
    }, 
    "filesGlob": [ 
    "./src/**/*.ts", 
    "./test/**/*.ts", 
    "./typings/index.d.ts", 
    "./custom_typings/**/*.d.ts", 
    "./jspm_packages/**/*.d.ts" 
    ], 
    "exclude": [ 
    "node_modules", 
    "jspm_packages", 
    "dist", 
    "build", 
    "test" 

    ], 
    "atom": { 
    "rewriteTsconfig": false 
    } 
} 

我试着用以下指定的data的类型,但它并没有解决问题,虽然该错误消息是不同的,两者如下所示:

interface TokenResult 
{ 
    accessToken: string; 
    expiryDate: string; 
}  

.... 

public refreshToken(): Promise<BearerToken> 
{ 
    let token: BearerToken = new BearerToken(); 
    token.accessToken = "no_data"; 
    token.expiryDate = new Date(Date.now().toString()); 

    return this.http.fetch('/Account/getToken') 
     .then(response => response.json()) 
     .then((data: TokenResult) => 
     {     
      console.log('ApiToken.refreshToken returned data: ' + data); 

      token.accessToken = data.accessToken; 
      token.expiryDate = new Date(data.expiryDate); 

      return token; 
     }) 
     .then((t) => { return this.saveToken(t) }); 
} 

而错误是:

error TS2345: Argument of type '(data: TokenResult) => BearerToken' is not assignable to parameter of type '(value: Response) => BearerToken | PromiseLike<BearerToken>'. 
    Types of parameters 'data' and 'value' are incompatible. 
    Type 'Response' is not assignable to type 'TokenResult'. 
     Property 'accessToken' is missing in type 'Response'. 

我从gitter的贡献者那里找到了答案。一个演员阵容到any,然后演员阵容到TokenResult做的伎俩,如下...

return this.http.fetch('/Account/getToken') 
    .then(response => response.json()) 
    .then((data: any) => 
    { 
     console.log('ApiToken.refreshToken returned data: ' + data); 

     token.accessToken = (<TokenResult>data).accessToken; 
     token.expiryDate = (<TokenResult>data).expiryDate; 

     return token; 
    }) 
    .then((t) => { return this.saveToken(t) }); 
+0

有同样的问题。宣布(数据:任何)为我们做了诀窍。在我们的情况下,没有必要进一步演员 – eMBee