Closed tobiasBora closed 6 months ago
I think the last line in the constructor is confusing typescript. It's not needed so you should skip it.
Thanks for your answer, sadly removing this lines changes nothing. I get this error on db.decks.update(file.id, …)
, delete
, update
, any custom function waiting for a number
…
Oh, funnily, if I do files!: Table<File>;
instead of files!: Table<File, number>
, all errors regarding update
, delete
and update
vanish. But it still raises an error on functions I created like:
function moveFileUp(id: number) {
db.transaction("rw", db.files, async () => {
const fileToMove = await db.files.get(id);
if (fileToMove) {
const pos = fileToMove.position;
// We try to update: if no object is updated, there is no object above
const nbObjectModified = await db.files.where({position: pos-1}).modify(item => {++item.position});
if (nbObjectModified == 1) {
await db.positions.where({id: id}).modify(item => {--item.position});
}
}
});
}
…
<button on:click={() => moveFileUp(file.id)}><Icon.CaretUpOutline/></button>
as I get an error:
Error: Argument of type 'number | undefined' is not assignable to parameter of type 'number'.
Type 'undefined' is not assignable to type 'number'. (ts)
<button on:click={() => moveFileUp(file.id)}><Icon.CaretUpOutline/></button>
Auto-incremented keys on your entities are only optional when adding/putting them but is 'required' (certain to not be undefined) when retrieving things back via toArray(), get() etc. In typescript you can use the !
to remove undefined from your type. Since your id
is declared optional but it's actually required (if retrieved from dexie), you may just add a !
like this: file.id!
.
Dexie 4 has also a better solution for this, see release notes of dexie 4:
interface Friend {
id: number;
name: string;
age: number;
}
class MyDB extends Dexie {
friends!: EntityTable<Friend, 'id'>; // Automatically makes `id` optional when adding and picks its TKey type.
}
As you see here, id
shall be declared without the question mark and will still be considerd optional in calls to add()
and put()
etc - so it mirrors the actual typings a bit better and you won't have to do the !
everywhere.
Thanks… but I tried this (with dexiejs from Master), and I get many errors. Now, my custom functions seem to be better recognized, but update
/delete
broke:
Error: Argument of type 'number' is not assignable to parameter of type 'File | "id"'. (ts)
I also get a new kind of error on get
:
Error: No overload matches this call.
Overload 1 of 4, '(key: "id"): PromiseExtended<File | undefined>', gave the following error.
Argument of type 'number' is not assignable to parameter of type '"id"'.
Overload 2 of 4, '(equalityCriterias: { [key: string]: any; }): PromiseExtended<File | undefined>', gave the following error.
Argument of type 'number' is not assignable to parameter of type '{ [key: string]: any; }'. (ts)
db.transaction("rw", db.files, async () => {
const fileToMove = await db.files.get(id);
if (fileToMove) {
I also can't create a new entry:
Error: Argument of type '{ name: string; slug: string; description: string; position: number; }' is not assignable to parameter of type 'Deck'.
Property 'id' is missing in type '{ name: string; slug: string; description: string; position: number; }' but required in type 'File'. (ts)
db.transaction("rw", db.files, async () => {
const id = await db.files.add({
name: newFileName,
slug: slug,
description: "Click me to edit this description",
position: $decks.length
});
Here is my code:
// Each file is made of decks
export interface File {
// Make sure to update the associated class below
id: number;
name: string; //
slug: string;
description: string;
position: number;
}
export class MyDb extends Dexie {
files!: Table<File, 'id'>;
constructor(name : string) {
super(name);
this.version(1).stores({
files: '++id, name, slug, position', // Primary key and indexed props
});
}
}
EntityTable
not Table
.
I've updated the docs around this. See https://dexie.org/docs/Typescript
Ohh, good point awesome, thanks a lot! Just a minor point, the doc has a typo, one must use import Dexie, { type EntityTable } from "dexie";
not import Dexie, { EntityTable } from "dexie";
Good point. But I think it's not mandatory to use the type specifier even though it's clearer to read - or do you get an error when using import Dexie, { EntityTable } from "dexie"
? Just curious.
I did get an error
Ok thanks. I think babel complains while typescript doesn't then. I'll fix it!
If I create a new table like:
then each time I use
file.id
(e.g. in{#each $files as file (file.id)} The id is <button on:click="{e => db.files.delete(file.id)}"/> {/if}
) I get many errors like:on the other hand, if I write
id:
instead ofid?:
in the typescript spec, then I get errors when I try to create entry as id is not provided. Is this a bug or am I doing something stupid here?