Skip to content

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

Open
@Woodz

Description

@Woodz

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

Activity

added
status: needs triageIssues which needs to be reproduced to be verified report.
type: fixIssues describing a broken feature.
on Sep 24, 2024
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

    status: needs triageIssues which needs to be reproduced to be verified report.type: fixIssues describing a broken feature.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Woodz

        Issue actions

          fix: `plainToInstance` with discriminated type union with no matching `subTypes` silently returns DTO · Issue #1762 · typestack/class-transformer