Skip to content

Automatic type inference for discriminators #16045

Description

@skrukwa

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

9.2.2

Node.js version

24.13.1

MongoDB server version

n/a

Typescript version (if applicable)

5.8.3

Description

I was hoping that discriminated schemas would be inferred as disjoint types so that I could handle models polymorphically with type-safe type-narrowing.

Am I doing something wrong? I got this code from the docs (although had to add the new keyword to Schema and MyModels.

Thanks!

Steps to Reproduce

const shapeSchema = new Schema({ name: String }, { discriminatorKey: 'kind' });
const schema = new Schema({ shape: shapeSchema });

schema.path<Schema.Types.Subdocument>('shape').discriminator('Circle', new Schema({ radius: String }));
schema.path<Schema.Types.Subdocument>('shape').discriminator('Square', new Schema({ side: Number }));

const MyModel = mongoose.model('ShapeTest', schema);

// If `kind` is set to 'Circle', then `shape` will have a `radius` property
const circleDoc = new MyModel({ shape: { kind: 'Circle', radius: 5 } });
const squareDoc = new MyModel({ shape: { kind: 'Square', side: 10 } });


for (const doc of [circleDoc, squareDoc]) {

    if (doc.shape?.kind === 'Circle') { // Property 'kind' does not exist on type '{ name?: string | null | undefined; }'.
        doc.shape.radius;               // Property 'radius' does not exist on type '{ name?: string | null | undefined; }'.
    }

    if (doc.shape?.kind === 'Square') { // Property 'kind' does not exist on type '{ name?: string | null | undefined; }'.
        doc.shape.side;                 // Property 'side' does not exist on type '{ name?: string | null | undefined; }'.
    }
}

Expected Behavior

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    typescriptTypes or Types-test related issue / Pull Request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions