Skip to content

Include Standard Schema types property for Type Inference #16339

Description

@tomkel

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.7.1

Node.js version

26.3.1

MongoDB server version

8.3.4

Typescript version (if applicable)

6.0.3

Description

The Standard Schema Props interface is supposed to have a types property. This is so that other Standard Schema libraries are able to do type inference properly.

export interface Props<Input = unknown, Output = Input> {
  ...
  /** Inferred types associated with the schema. */
  readonly types?: Types<Input, Output> | undefined;`
}
...
/** The Standard Schema types interface. */
export interface Types<Input = unknown, Output = Input> {
  /** The input type of the schema. */
  readonly input: Input;
  /** The output type of the schema. */
  readonly output: Output;
}

/** Infers the input type of a Standard Schema. */
export type InferInput<Schema extends StandardSchemaV1> = NonNullable<
  Schema['~standard']['types']
>['input'];

/** Infers the output type of a Standard Schema. */
export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<
  Schema['~standard']['types']
>['output'];

Here's the current mongoose definition

mongoose/types/models.d.ts

Lines 111 to 119 in 03bedea

export namespace StandardSchemaV1 {
export interface Props<Output = unknown> {
readonly version: 1;
readonly vendor: 'mongoose';
readonly validate: (
value: unknown,
options?: Options | undefined
) => Result<Output> | Promise<Result<Output>>;
}

In it's current form, types are always unknown when used with other libraries that are using InferInput and InferOutput , which isn't very great. It's JS-only for me at this point.

I am trying to use it with hono standard validator, which uses InferInput and InferOutput:
https://github.com/honojs/middleware/blob/a401fee0e0d3c20b4a0b84349043b82932d9571f/packages/standard-validator/src/index.ts#L116-L117

Steps to Reproduce

const Profile = model('Profile', new Schema({ profile: { type: Schema.Types.ObjectId, required: true } })
const app = new Hono()
app.post('/post', sValidator('json', Profile), (c) => {
  const valid = c.req.valid('json')

  expect(valid).toEqual({ profile: new Types.ObjectId(profileId) }) // JS works
  expectTypeOf(valid).not.toEqualTypeOf<{ profile: string }>()
  expectTypeOf(valid).not.toEqualTypeOf<{ profile: Types.ObjectId }>()
  expectTypeOf(valid).toEqualTypeOf<unknown>() // TS does not

  return c.text('ok', 200)
})

Expected Behavior

types exists on StandardSchemaV1.Props interface so that InferInput and InferOutput work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions