Skip to content

plainToClass assumes response is an array #97

Open
@NathanHazout

Description

@NathanHazout

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'.
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??

Activity

gempain

gempain commented on Oct 10, 2017

@gempain
Contributor

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 :)

rightisleft

rightisleft commented on Mar 27, 2018

@rightisleft

While that works - it seems a bit redundant?

davidquintard

davidquintard commented on Mar 11, 2019

@davidquintard

Hi there,
What about this issue?

DimiTech

DimiTech commented on Apr 23, 2019

@DimiTech

Hello, I'm interested in this as well! Thanks!

jasperblues

jasperblues commented on May 27, 2019

@jasperblues

To array:

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

To single:

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

^-- a little less redundant.

Edit: Just came here in 2024 and chose one of the higher in the thread (and slightly redundant) answers, not realizing I'd found a better way in 2019 :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: documentationIssues related to improving the documentation.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @NathanHazout@jasperblues@rightisleft@NoNameProvided@gempain

        Issue actions

          plainToClass assumes response is an array · Issue #97 · typestack/class-transformer