【问题标题】:Need help resolving an Angular 9 TypeScript Error (TypeCasting)需要帮助解决 Angular 9 TypeScript 错误(TypeCasting)
【发布时间】:2020-06-04 17:18:39
【问题描述】:

我已经将 Angular 从 4 更新到 9,现在,在能够让它工作之后,仍然遇到一些我无法解决的错误。

我的代码:

this.getTrades().then( ( trades ) => {
    console.log( trades );
    this.trades = new MatTableDataSource<Trade>( trades );
});

getTrades() {
    let promise = new Promise( ( resolve, reject ) => {
        this.dataService.getTrades().subscribe( ( trades ) => {
            resolve( trades );
        });
    });
    return promise;
}

export interface Trade {
    ID: number;
    UserID: number;
    DateTime: Date;
    Exchange: Exchange;
    BaseCoin: Coin;
    MarketCoin: MarketCoin;
    Price: number;
    Amount: number;
    Total: number;
    Last: number;
    Type: Type;
    Status: Status;
    Symbol: string;
}

getTrades() 数据源:

getTrades() {

    return this.http.get( 'http://localhost:8888/currencytracker-api/json/get-trades.php' ).pipe(
    map( res => res.json() ));

}

getTrades() 返回一个包含以下数据的 json 数组:

ID: 1
UserID: 1
DateTime: "2017-12-25T00:00:00+0000"
Exchange: {ID: 1, Title: "BitTrex"}
BaseCoin: {ID: 718, Abbr: "BTC"}
MarketCoin: {ID: 743, Abbr: "XVG"}
Price: "0.000013470000"
Amount: "1019.014328640000"
Total: 0.0137261230067808
Last: "0.000005470000"
Type: {ID: 1, Title: "Limit Buy"}
Status: {ID: 2, Title: "Closed"}
Symbol: "Ƀ"

这是我得到的错误:

src/app/components/trades/trades.component.ts:100:68 中的错误 - 错误 TS2345:“未知”类型的参数不可分配给“交易[]”类型的参数。类型“{}”缺少类型“Trade[]”的以下属性:length、pop、push、concat 等 26 个。

this.trades = new MatTableDataSource( trades );

任何帮助理解此错误并解决它将不胜感激。谢谢。

更新

当我声明交易变量时,我是这样做的:

Trade[]

相反,我现在将其声明为:

MatTableDataSource<Trade>

【问题讨论】:

    标签: angular typescript casting


    【解决方案1】:

    您需要更明确地说明类型:

    首先,使用最方便的HttpClient.get 重载,它需要一个泛型参数并将正文解释为 JSON。

    构造一个 GET 请求,将主体解释为 JSON 对象并返回 给定类型的响应正文。

    getTrades(): Observable<Trade[]> {
        return this.http.get<Trade[]>( 'http://localhost:8888/currencytracker-api/json/get-trades.php' );
    }
    

    然后,将显式类型添加到 getTrades()

    getTrades(): Promise<Trade[]> {
        const promise = new Promise<Trade[]>( ( resolve, reject ) => {
          this.dataSource.getTrades().subscribe( ( trades ) => {
            resolve( trades );
          });
        });
        return promise;
      }
    

    更好的是,放弃对promise的转换,直接订阅dataSource返回的Observable

    this.dataSource.getTrades().subscribe( ( trades ) => {
        console.log( trades );
        this.trades = new MatTableDataSource<Trade>( trades );
    });
    

    更新

    检查您是否使用来自@angular/common/http 的HttpClient,而不是来自@angular/core 的HttpClient。 @angular/http 包随着 @angular/common/http 的到来而被弃用,并在 Angular 8 中被删除。

    https://www.npmjs.com/package/@angular/http

    不再支持包。请改用@angular/common,见https://angular.io/guide/deprecations#angularhttp

    更新 2 你的分配问题表明它总是不正确的。 MatTableDataSource&lt;Trade&gt; 不是 Trade[]

    我坚信它在您的旧项目中起作用的原因是您使用了 打字稿 2.x。因此getTrades() 被推断为Promise&lt;any&gt; 使用 Typescript 3.x getTrades()(没有显式输入)被推断为 Promise&lt;unknown&gt;

    https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type

    TypeScript 3.0 引入了一个新的顶级类型unknownunknownany 的类型安全对应物。任何东西都可以分配给unknown,但unknown 不能分配给任何东西,除了它自己和任何没有类型断言或基于控制流的缩小。同样,在没有先声明或缩小到更具体的类型之前,不允许对 unknown 进行任何操作。

    【讨论】:

    • getTrades(): Observable { return this.http.get( 'localhost:8888/currencytracker-api/json/get-trades.php' ); } 返回以下消息:Expected 0 type arguments, but got 1.
    • 谢谢,解决了这个消息,但是这个建议 this.dataService.getTrades().subscribe( ( trades ) => { this.trades = new MatTableDataSource( trades ); }) ;仍在抛出一条消息,即:“MatTableDataSource”类型缺少“Trade[]”类型中的以下属性:长度、弹出、推送、连接和另外 24 个。 this.trades = new MatTableDataSource( trades );
    • 这表明您将this.trades 字段键入为Trade[],并且您正在尝试为其分配值MatTableDataSource&lt;Trade&gt;。这是不可能的 - MatTableDataSource&lt;Trade&gt; 不是 Trade[]
    • 不太确定我是否理解。我理解 Trade 不是 Trade[],而 this.trades 是 Trade[](trades: Trade[];)。此外,如果我是正确的,dataService.getTrades() 的返回值(交易)是 Trade[]。但我无法让这个工作:this.trades = new MatTableDataSource(trades);也试过 this.trades = new MatTableDataSource( trades );
    【解决方案2】:

    在 Promise 回调中订阅不是一个好习惯。 It might lead to memory leaks.

    如果您需要将 Observable 转换为 Promise,请使用 toPromise()

    尝试强类型getTrades()

    getTrades(): Promise<Trade[]> {
        return this.dataService.getTrades().toPromise()      
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 2021-09-10
      • 2021-12-11
      • 1970-01-01
      相关资源
      最近更新 更多