-
Type: Bug
-
Resolution: Duplicate
-
Priority: Critical - P2
-
None
-
Affects Version/s: 4.1.0
-
Component/s: None
-
Environment:Typescript 4.3.5 in Node 14.7
-
Empty show more show less
-
Not Needed
What problem are you facing?
When querying a collection in Typescript with a projection, we used (driver 3.x) to be able to specify a filter on the type that the collection contains but specify a different generic type in the find() call so that the cursor returned was of a different shape that the one we filtered.
We have used this feature pervasively.
When migrating to v4x of the driver, the typing has changed in such a way that the previous scenario is no longer supported, that is, the generic argument specifies not only the type of the filter but also the cursor type. As a result, we cannot filter on properties that we are not returning in the projection which, obviously is far from ideal and would make us have to change tons of types to accommodate those properties that we are querying on but not returning.
The previous (working) typing:
interface Collection<TSchema extends { [key: string]: any } = DefaultSchema> {
{{ ...}}
{{ find<T = TSchema>(query: FilterQuery<TSchema>, options: FindOneOptions<T extends TSchema ? TSchema : T>): Cursor<T>;}}
{{ ...}}
}
The new (more restrictive and arguably worse for our interest):
class Collection<TSchema extends Document = Document> {
{{ ...}}
{{ find<T = TSchema>(filter: Filter<T>, options?: FindOptions<T>): FindCursor<T>;}}
{{ ...}}
}
What driver and relevant dependency versions are you using?
Native driver 4.1.0
Steps to reproduce?
If you are using driver v3.x one can do code like this:
interface Doc {
{{ _id: ObjectId}}
{{ name: string}}
{{ discriminator: number}}
}
type Projection = Omit<Doc, "discriminator">
const collection: Collection<Doc>
const filter: FilterQuery<Doc> = {
{{ discriminator: 42}}
}
const projection: SchemaMember<Projection, boolean> = {
{{ _id: true,}}
{{ name: true}}
}
const projections: Projection[] = await collection.find<Projection>(filter, { projection }).toArray()
Whereas when using the driver 4.x we cannot:
const filter: Filter<Doc> = {
{{ discriminator: 42}}
}
const projection: SchemaMember<Projection, boolean> = {
{{ _id: true,}}
{{ name: true}}
}
{{const props: FindOptions<Projection> = }}
const projections: Projection[] = await collection.find<Projection>(filter, { projection }).toArray()
Compiler complains about the fact that Projection does not have a "discriminator" property and we would have to change the projection type to contain an optional discriminator that is used only for querying but would confuse clients of the data returned unless further property filtering is done. Not ideal for something that used to work beautifully out-of-the-box.
Please, revert back to the previous, more flexible implementation, otherwise we will not be able to use the newest drivers and migrate our Atlas clusters to 5.
- is duplicated by
-
NODE-3468 Type definitions are buggy
- Closed