Dexie.js icon indicating copy to clipboard operation
Dexie.js copied to clipboard

`get` types can match incorrectly at times

Open Shadowfiend opened this issue 4 years ago • 2 comments

The type overloading for get, which allows both the primary index type and an object with filter keys, can lead to cases where an index type is attempted to be used incorrectly. In particular, because of TypeScript's design, {[key:string]:any} effectively matches any object, including arrays.

Here are the overloads in question:

https://github.com/dfahlander/Dexie.js/blob/b6a1236b17324fc53fe8440b3f3de50f7347916a/src/public/types/table.d.ts#L19 https://github.com/dfahlander/Dexie.js/blob/b6a1236b17324fc53fe8440b3f3de50f7347916a/src/public/types/table.d.ts#L21

Here's an example of where this falls over:

arrayIndexTable: Dexie.Table<{ firstName: string, lastName: string }, number> // primary index is set to `number`

// initialized as:
//         "&[firstName+lastName],firstName,lastName",

// TypeScript is a-okay with this!
const existing = arrayIndexTable.get(["Shadow", "Fiend"])

Ideally, the above would fail at the type level before hitting a confusing lack of results. Unfortunately, it doesn't, because an array matches {[key:string]:any}. An easy fix for the particular problem is:

get(equalityCriterias: {[key:string]:unknown}): PromiseExtended<T | undefined>; 

However, I don't have the depth here to understand if this would yield too much pain internally to the implementations of these functions, but I believe it's effectively saying the same thing while disallowing incompatible types like arrays.

Shadowfiend avatar Sep 01 '21 21:09 Shadowfiend

Thanks. I will look into it. The internal implementation wouldn't be harmed by changing the type - so it would just be to change it and verify that it still compiles.

Side note: "&[firstName+lastName],firstName,lastName" would actually mean that the primary key is an array of the two items [firstName, lastName]. Adding a leading comma would make the primary key outbound and allow a non-property as key.

dfahlander avatar Sep 01 '21 22:09 dfahlander

Got it! Making the array the primary key was my goal with the example here---with the type of the primary key set to number despite being a [string, string]. Not sure if I messed that up though? 😅

Shadowfiend avatar Sep 02 '21 18:09 Shadowfiend