简体   繁体   中英

Why is typescript disregarding a variable type?

I declared a typed variable that will supposedly hold the data fetched by a service. However, the returned data is not the same type as the variable, yet the variable still accepts the data.

Here is my code:

Data: Array<{Currency: string, Rate: number}>;

getData(): void {
  this.DataService.getAll().subscribe(
    (res: Array<any>) => {
      this.Data = res;
    },
    (err) => {
      console.log(err);
    }
  );
}

I tried the following but it still didn't work:

res: Array<{Currency: string, Rate: number}>

Update

This is my service

getAll(): Observable<Array<{Currency: string, Rate: number}>> {
    return this.http.get(`${this.baseUrl}/data`).pipe(
      map((res) => {
        this.data = res['data'];
        return this.data;
    }),
    catchError(this.handleError));
  }

UPDATE 2

I found the similar issue here: https://github.com/angular/angular/issues/20770

You can create a model as:

export interface CurrencyModel {
  Currency: string,
  Rate: number
}

then use this model in response as:

Data: CurrencyModel[];

getData(): void {
  this.DataService.getAll().subscribe(
    (res: CurrencyModel[]) => {
      this.Data = res;
    },
    (err) => {
      console.log(err);
    }
  );
}

getAll should return Observable<CurrencyModel[]>

Because there is no type safety at runtime.

Remember TypeScript is translated into JavaScript at compile time. And at that point, all bets are off.

If you want to ensure some sort of type safety I recommend using something for API documentation with tooling for automated code generation like OpenAPI with swagger.

any is by definition assignable to anything. So Array<any> will be assignable to any other array type. I would avoid any at all cost. If you truly don't know the type of somethign use unknown instead and use explicit assertions as needed, better explicit assertions rather than silent any assignments.

Data: Array<{Currency: string, Rate: number}>;

getData(): void {
  this.DataService.getAll().subscribe(
    (res: Array<unknwon>) => {
      this.Data = res as Array<{Currency: string, Rate: number}>;
    },
    (err) => {
      console.log(err);
    }
  );
}

Ideally getAll() should return Observable<Array<{Currency: string, Rate: number}>> . The no type annotations would be necessary on res and it would all be type safe.

TypeScript is an extension on top of JavaScript that provides type support for the process of writing code . Anyways, all your TypeScript code will be converted to pure JavaScript before you can run your program. Thus, after compilation all your types will be lost in reality.

If your returned data at runtime do not have the same type as the variable you declared, there is no chance for TypeScript to warn you or prevent this. This is because TypeScript can only check static types , not dynamic types like if you receive a server response. You'll need another validation mechanism to verify your server data correspond to your TypeScript definition.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM