Reputation: 1353
I'm looking for help with TypeScript and the PouchDB type declarations. Consider this TS code:
import PouchDB = require('pouchdb')
import find = require('pouchdb-find')
PouchDB.plugin(find)
const data = new PouchDB("http://localhost:5984/data"),
export async function deleteLastRevForIds(dbname, ids) {
const docsToDelete = await data.find({
fields: ["_id", "_rev"],
selector: { _id: { $in: ids } }
})
const deletePromise = docsToDelete.docs.map(doc => {
return data.remove(doc) // <-- HERE TSC SHOUTS AT ME about `doc`
})
const deletion = await Promise.all(deletePromise)
return deletion
}
At the annotated remove()
call, tsc
emits this error:
Argument of type 'IdMeta' is not assignable to parameter of type 'RemoveDocument'.
Type 'IdMeta' is not assignable to type 'RevisionIdMeta'.
Property '_rev' is missing in type 'IdMeta'.'
What's happening is that the find()
call is typed by the DefinitelyTyped typings
as returning a {docs: PouchDB.Core.IdMeta[]}
. And as its name implies,
a PouchDB.Core.IdMeta[] means an array of {_id: string}
.
But it's false! PouchDB.find()
doesn't return just a list of {_id: ...}
objects,
it returns a list of {_id: ..., _rev: ...}
(plus I asked for these two fields explicitly). Or am I missing something?
As a result, when calling the remove()
function (correctly typed by the DT typings as
needing an fully-specified _id+_rev RevisionIdMeta
) with such an object, TS rightly shouts at me.
I tried casting this thing in all directions but couldn't bend it to my will; tsc
keeps erroring that _rev
is missing from my object.
Also, should I propose a change to the DT typings?
Thanks.
Upvotes: 2
Views: 780
Reputation: 399
Yeah, the Pouchdb-find definitions are wrong. Something like this should get you moving...
const data = new PouchDB("http://localhost:5984/data")
interface FixedFindResponse<Content extends PouchDB.Core.Encodable> {
docs: PouchDB.Core.ExistingDocument<Content>[];
}
export async function deleteLastRevForIds(dbname: void, ids: number[]) {
const docsToDelete: FixedFindResponse<any> = await data.find({
fields: ["_id", "_rev"],
selector: { _id: { $in: ids } }
})
const deletePromise = docsToDelete.docs.map(doc => {
return data.remove(doc) // <-- HERE TSC SHOUTS AT ME about `doc`
})
const deletion = await Promise.all(deletePromise)
return deletion
}
Upvotes: 3
Reputation: 52193
Is there a way for me do such a "deep" cast?
You can always re-cast something using as any as Whatever
. Obviously, this should be a last resort if you can't get the types correct, because there's no safety around the assertion whatsoever. For example 123 as any as Window
compiles.
is there a way to override the DT typings as locally as possible?
Yes, take a look at Declaration Merging: Module Augmentation.
Should I be doing something else entirely?
If you're sure the type definitions are wrong you could always patch them and submit a PR to DefinitelyTyped.
Upvotes: 2