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