2

I just spent 4 hours troubleshooting typescript error

Object literal may only specify known properties, and 'details'
does not exist in type 'Readonly<{ [x: `details.${string}.value`]:
{ value: string; type: string; } | undefined; [x: `details.${string}.type`]:
{ value: string; type: string; } | undefined;

and clearly, I can see there is 'details' in the object whatever tsc is complaining on. Literally, I have other functions on the same file working without typescript errors.

Long story short, Controller will invoke Service with a single parameter and its type is defined on Controller file but then Service needs to know what type of data its getting so Service file has import statement pointing to Controller

Controller

import service from './Service'
export type DataType = {...}

const data:DataType = fetch()
service(data)

Service

import DataType from './controller'

export function service(data:DataType) {
  // typescript error
  someOtherFunctionCall<DataType>(data)
}

I think it's a pretty basic pattern. When I deleted import statement from service file, the error went away and of course, copy/pasted type definition. Weird thing is that error didn't show up again when I pasted exactly the same line. Is it expected behavior? I've heard nodejs can handle not very complicated circular imports. But this happened, should I not use circular imports?

Below are code from my project

Category.ts

export default interface Category {
  _id: ObjectId
  details: Record<
    string,
    {
      value: string
      type: string
    }
  >
  ...
}

controller.ts

import { updateItem } from './service'

export interface ScrapItem {
  _id: ObjectId
  details: Record<
    string,
    {
      value: string
      type: string
    }
  >
  ...
}

const item:ScrapItem = scrapSomeItem()
updateItem(item)

service.ts

import Category from 'models/category'
import ScrapItem from './controller'
import db from 'MongodbHelper'

export async function updateItem(item: ScrapItem): Promise<void> {
  const db = await getDb()
  const categoryCollection = db.collection<Category>(category)

  await categoryCollection.updateOne(
    {
      _id
    },
    {
      $set: {
        // THIS IS WHERE I GET ERROR
        // Object literal may only specify known properties, and 'details' does not exist in type ...
        details,
        ...
      }
    },
    {
      upsert: true
    }
  )
}

I'm getting typescript error on service.ts where I call one of mongodb driver method updateOne. The only workaround here is to delete Category from const categoryCollection = db.collection<Category>(category) or add | any to details type definition on category.ts.

  • Welcome to SO! Would you please [edit] your question and copy-paste the definition of `someOtherFunctionCall` too? – lepsch Jul 22 '22 at 06:09
  • @lepsch Sure but to make sense, I feel like I gotta post part of code too which is a bit long and redundant. Before I do that I will just let you know what someOtherFunctionCall is. – swimming_polar Jul 22 '22 at 19:31
  • You can strip it down a bit... no problem. The important part is the function's type definition – lepsch Jul 22 '22 at 19:32
  • @lepsch You know what I think I didn't correct the error. I ll try to edit the post and add part of code in a coupe of days. Make some rearrangement, pick what part to upload. But to answer your last sentence, it was one of mongodb methods (collection.updateOne). – swimming_polar Jul 22 '22 at 20:04
  • @lepsch I just edited the question and put some actual code from project. Would this be helpful? – swimming_polar Jul 23 '22 at 10:31

1 Answers1

1

This is actually a bug in the mongodb version 4.8 typing declaration files. It has been fixed already on the main branch 3 days ago (2022-07-20) but there is no release yet. The latest release, the 4.8 version at the time of this writing, is from 10 days ago (2022-07-13).

To fix the problem downgrade the version to 4.7:

npm i mongodb@~4.7.0

Or install from the main branch where the fix is already inplace:

npm i "https://github.com/mongodb/node-mongodb-native#05e007b0b5ff98151c3ff972ee2f881b4203639e"
lepsch
  • 8,927
  • 5
  • 24
  • 44
  • Thanks for the reply. Downgrading mongodb to 4.7.0 did the trick. I kinda thought may be it's a bug but didn't know where to look for! I spent almost half of my day trying to fix this. Again thank you – swimming_polar Jul 23 '22 at 22:37