plainToClass assumes response is an array

See original GitHub issue

Given the following code:

getProposal(id: string) : Promise<Proposal> {
    const url = `${this.proposalsUrl}/${id}`;
    var headers = new Headers();
    this._authService.createAuthorizationHeader(headers);
    var options = new RequestOptions({ headers: headers });
    return this.http.get(url, options)
        .toPromise()
        .then(response => plainToClass(Proposal, response.json()));
}

I get the typescript error:

[ts] Type ‘Promise<Proposal[]>’ is not assignable to type ‘Promise<Proposal>’. Type ‘Proposal[]’ is not assignable to type ‘Proposal’. Property ‘id’ is missing in type ‘Proposal[]’.

How did it conclude that the response is an array??

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:3
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

17reactions
gempaincommented, Oct 10, 2017

You are having this issue because Typescript does not know the type of response.json(). This is because plainToClass (and some other methods from class-transformer) has multiple signatures. From src/index.ts:

/**
 * Converts plain (literal) object to class (constructor) object. Also works with arrays.
 */
export function plainToClass<T, V extends Array<any>>(cls: ClassType<T>, plain: V, options?: ClassTransformOptions): T[];
export function plainToClass<T, V>(cls: ClassType<T>, plain: V, options?: ClassTransformOptions): T;
export function plainToClass<T, V>(cls: ClassType<T>, plain: V|V[], options?: ClassTransformOptions): T|T[] {
    return classTransformer.plainToClass(cls, plain as any, options);
}

Since Typescript cannot determine the appropriate signature, I assume it just picks the first one, hence why it’s telling you that Proposal[] is expected.

To fix your problem, you simply need to explicitly declare the type of response.json() using as Proposal:

.then(response => plainToClass(Proposal, response.json() as Proposal));

And off you go 😃

6reactions
jasperbluescommented, May 27, 2019

To array:

plainToClass(Permission, <any[]>JSON.parse(response))

To single:

plainToClass(Permission, <any>JSON.parse(response))

^-- a little less redundant.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Exposing an array of object using class-transformer
I am not able to expose an array of objects. The Followers array is not getting exposed, even though I exposed in the...
Read more >
Class Transformer Array - StackBlitz
Blank starter project for building TypeScript apps.
Read more >
Handling date fields in JSON with Typescript | by Doron Tohar
When we call plainToClass(T, a) and a is an array of type T[] , it knows to map each element as class T...
Read more >
Serialization | NestJS - A progressive Node.js framework
Let's assume that we want to automatically exclude a password property from ... When this endpoint is requested, the client receives the following...
Read more >
Type-transformer - npm.io
You want to have an array of object of type Person , however, you only get plain objects: fetch('persons.json').then((response:Response) ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found