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

TypeScript: timestamps not inferred from schema #12069

Closed
2 tasks done
janickvwcotiss opened this issue Jul 7, 2022 · 9 comments
Closed
2 tasks done

TypeScript: timestamps not inferred from schema #12069

janickvwcotiss opened this issue Jul 7, 2022 · 9 comments
Labels
typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@janickvwcotiss
Copy link

janickvwcotiss commented Jul 7, 2022

Prerequisites

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

Mongoose version

6.4.0

Node.js version

18.2.0

MongoDB server version

5.0.9

Description

Hi there, my issue is to do with typescript.

The issue I am having is that when creating a document schema with timestamps enabled the inferred document type doesn't have the corresponding createdAt and updatedAt fields present.

This means that when querying documents through the schema typescript will throw the property doesn't exist on type issue for the createdAt and updatedAt fields.

Hope this is pretty simple to understand, I've done my best to proved a good code example to best explain the issue I am having.

I realised mongoose has just recently migrated to typescript and isn't fully feature complete yet so appreciate any help.

P.s. I realise I haven't manually typed the interface for the schema e.g. new Schema<IDocument> and export const Document = model<IDocument>('Document', DocumentSchema); this is because we are migrating our whole code base to typescript and would ideally like to save some time by using InferSchemaType. But obviously open to any ideas even if it'll end up requiring typing the interfaces manually.

Thanks.

Steps to Reproduce

import { Schema, model, Model, InferSchemaType } from 'mongoose';

const DocumentSchema = new Schema(
  {
    url: { type: String, required: true, unique: true },
    fileSize: { type: Number, required: true },
    mimeType: { type: String, required: true },
    fileName: { type: String, required: true },
  },
  {
    timestamps: true,
  }
);

// Document comes out as
// const Document: Model<{
//   url: string;
//   fileSize: number;
//   mimeType: string;
//   fileName: string;
// }, {}, {}, {}, any>
export const Document: Model<InferSchemaType<typeof DocumentSchema>> = model(
  'Document',
  DocumentSchema
);

async function findDocument(id: string) {
  // Document without timestamp in query
  const doc1 = await Document.findById(id);
  if (doc1) {
    console.log(doc1.createdAt); // Error: "Property 'createdAt' does not exist on type 'Document...'"
    console.log(doc1.updatedAt);// Error: "Property 'updatedAt' does not exist on type 'Document...'"
  }

  // With timestamp in query
  const doc2 = await Document.findById(id, undefined, { timestamps: true });
  if (doc2) {
    console.log(doc2.createdAt); // Error: "Property 'createdAt' does not exist on type 'Document...'"
    console.log(doc2.updatedAt); // Error: "Property 'updatedAt' does not exist on type 'Document...'"
  }
}

Expected Behavior

Expect the Document to have the timestamp fields present on the returned type.

@janickvwcotiss janickvwcotiss changed the title Timestamp properties not generated on TypeScript: timestamps not inferred from schema Jul 8, 2022
@vkarpov15 vkarpov15 added this to the 6.4.5 milestone Jul 8, 2022
@IslandRhythms IslandRhythms added the typescript Types or Types-test related issue / Pull Request label Jul 11, 2022
@vkarpov15 vkarpov15 modified the milestones: 6.4.5, 6.4.6 Jul 15, 2022
@jamesholcomb
Copy link

I am also converting a project to TS and experiencing this, however, an explicit interface seems to cause the same issue.

import { model, Schema } from "mongoose"

interface IPost {
  title: string
}

const postSchema = new Schema(
  {
    title: {
      type: String,
      required: true,
    },
  },
  {
    timestamps: true,
  }
)

const Post = model<IPost>("Post", postSchema)

Post.create({ title: "foo" }).then((post) => {
  console.log(post._id)
  console.log(post.createdAt) // property 'createdAt' does not exist on type 'Document<unknown, any, IPost> & IPost & { _id: ObjectId; }'.
})

Being a bit of TS noob, is there a workaround that does not require @ts-expect-error everywhere? It is reproducible in every 6.x release I tried.

@janickvwcotiss
Copy link
Author

janickvwcotiss commented Jul 17, 2022

I am also converting a project to TS and experiencing this, however, an explicit interface seems to cause the same issue.

import { model, Schema } from "mongoose"

interface IPost {
  title: string
}

const postSchema = new Schema(
  {
    title: {
      type: String,
      required: true,
    },
  },
  {
    timestamps: true,
  }
)

const Post = model<IPost>("Post", postSchema)

Post.create({ title: "foo" }).then((post) => {
  console.log(post._id)
  console.log(post.createdAt) // property 'createdAt' does not exist on type 'Document<unknown, any, IPost> & IPost & { _id: ObjectId; }'.
})

Being a bit of TS noob, is there a workaround that does not require @ts-expect-error everywhere? It is reproducible in every 6.x release I tried.

I know this isn't ideal but might help with your typescript errors until this is fixed in the next milestone?

interface IPost {
  title: string
  createdAt: Date;
  updateAt: Date;
}

const postSchema = new Schema<IPost>(
  {
    title: {
      type: String,
      required: true,
    },
  },
  {
    timestamps: true,
  }
)

const Post = model<IPost>("Post", postSchema)

Post.create({ title: "foo" }).then((post) => {
  console.log(post._id)
  console.log(post.createdAt) // (property) IPost.createdAt: Date
})

@Uzlopak
Copy link
Collaborator

Uzlopak commented Jul 18, 2022

@mohammad0-0ahmad

@mohammad0-0ahmad
Copy link
Contributor

mohammad0-0ahmad commented Jul 18, 2022

Thanks for mention @Uzlopak !
All changes that are related to schema options will be covered soon, but I am waiting for merging the PR related to virtuals paths, then I will start to cover schema options as I told.

@shoeferlin
Copy link

Experiencing the same issue. Looking forward to a fix!

@neocameback
Copy link

Could you try to access with following
post['createdAt']
instead of
post.createdAt

@janickvwcotiss
Copy link
Author

Could you try to access with following post['createdAt'] instead of post.createdAt

Doesn't make a difference

@Adizbek
Copy link

Adizbek commented Oct 15, 2022

@janickvwcotiss @neocameback
For quick fix, you can try to use SchemaTimestampsConfig
image

@vkarpov15 vkarpov15 modified the milestones: 6.x Unprioritized, 6.8 Oct 24, 2022
vkarpov15 added a commit that referenced this issue Nov 27, 2022
vkarpov15 added a commit that referenced this issue Nov 27, 2022
vkarpov15 added a commit that referenced this issue Nov 29, 2022
Infer timestamps option from schema
@Michstery
Copy link

Michstery commented Jun 24, 2024

Personally I just solved mine by delegating the object TYPE ( i.e Object variable not the model itself) to ANY instead of ObjectId in my code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
typescript Types or Types-test related issue / Pull Request
Projects
None yet
Development

No branches or pull requests

10 participants