I want to share something that can become a little of a headache for my users of the Dexie.js library. I'm not advocating for a change (because I haven't deep-dived into the implications), just want to share this so there is an awareness of this issue.
I'm the author of Dexie.js and have had to deal with this lately - to overcome the problems that occur due to the fact that uninitialized properties are implicitly initialized to undefined under the hood. And that does not play well with IndexedDB in certain scenarios.
Basically, we have a DOM system (IndexedDB) that distinguishes between {name: "Foo"}
and {id: undefined, name: "Foo"}
. The latter will fail in the call to IDBObjectStore.prototype.add() if the object store has the autoIncrement flag. This becomes a real problem for current Typescript users as the declaration of fields are for the purpose of typing - not initializing. I have a feeling this could be an issue generally on various libs - not just Dexie or IndexedDB libraries that change behaviour due to existing properties. And the user's intent of the prop declaration is not very obvious.
Example
class Friend {
id?: number;
name: string;
constructor(name) {
this.name = name;
}
}
const db = new Dexie("friendsDB");
db.version(1).stores({
friends: "++id, name" // "++id" makes the key autoIncremented
});
await db.friends.add(new Friend("foo"));
With babel's "plugin-transform-typescript" the class Friend transpiles to
class Friend {
id; // Here's the problem. id will be set to undefined.
name;
constructor(name) {
this.name = name;
}
}
I've "fixed" this problem in Dexie by working around the specific scenario by rewriting the input object and removing undefined props from it before passing it to IDB. But what other systems out there will have to introduce workarounds due to this behavior?