Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: plainToInstance with discriminated type union with no matching subTypes silently returns DTO #1762

Open
Woodz opened this issue Sep 24, 2024 · 0 comments
Labels
status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature.

Comments

@Woodz
Copy link

Woodz commented Sep 24, 2024

Description

Minimal code-snippet showcasing the problem

import { Type, plainToClass } from "class-transformer";

export abstract class Photo {
  id: number;
  filename: string;

  abstract getTitle(): string;
}

export class Landscape extends Photo {
  panorama: boolean;

  getTitle(): string {
    return `Landscape ${this.id} ${this.filename} ${this.panorama}`;
  }
}

export class Portrait extends Photo {
  person: Person;

  getTitle(): string {
    return `Portrait ${this.id} ${this.filename} ${this.person}`;
  }
}

export class UnderWater extends Photo {
  depth: number;

  getTitle(): string {
    return `UnderWater ${this.id} ${this.filename} ${this.depth}`;
  }
}

export class Album {
  id: number;
  name: string;

  @Type(() => Photo, {
    discriminator: {
      property: "__type",
      subTypes: [
        { value: Landscape, name: "landscape" },
        { value: Portrait, name: "portrait" },
        { value: UnderWater, name: "underwater" }
      ]
    }
  })
  topPhoto: Landscape | Portrait | UnderWater;
}

const validJsonInput = {
  id: 1,
  name: "foo",
  topPhoto: {
    id: 9,
    filename: "cool_wale.jpg",
    depth: 1245,
    __type: "underwater"
  }
};
const validAlbum = plainToClass(Album, validJsonInput);
console.log(validAlbum.topPhoto.getTitle());

const invalidJsonInput = {
  id: 2,
  name: "bar",
  topPhoto: {
    id: 10,
    filename: "random.jpg",
    __type: "unknown type"
  }
};
const invalidAlbum = plainToInstance(Album, invalidJsonInput); // <-- I would expect this method to throw an error since `unknown type` does not match a discriminated subType
console.log(invalidAlbum.topPhoto.getTitle()); // <-- However, it returns `invalidAlbum`, but `topPhoto` is the original DTO so methods fail with `invalidAlbum.topPhoto.getTitle is not a function`

Repro sandbox: https://codesandbox.io/p/sandbox/class-transformer-x3mbz

Expected behavior

I expect plainToInstance to throw an error if the discriminator property had a value that didn't match any subtype

Actual behavior

It silently returns the original DTO

@Woodz Woodz added status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature. labels Sep 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature.
Development

No branches or pull requests

1 participant