Dexie Typescript without Classes
When I began working with the Dexie IndexedDB wrapper library, I was disappointed to see the instructions that directed you to subclass Dexie
in order to use it with Typescript.
I would much prefer a composable pattern which didn’t use the syntactic sugar of ES classes.
Here is one technique for using Dexie and Typescript without classes.
TL;DR:
We’ll start off by importing Dexie
as BaseDexie
, so we can re-export an extended, genericDexie
type if we’d like to. We’ll create a type DexieTables
that we can use to implement our generic.
// db/index.ts
import BaseDexie from 'dexie';
type DexieTables = {};
export type Dexie<T extends any = DexieTables> = BaseDexie & T;
export const db = new BaseDexie('j5bot') as Dexie;
In a separate file, so things are composable, we create our first table/collection:
// db/tables/friends.ts
import { Table } from 'dexie';
export type Friend = {
id?: number;
name: string;
age: number;
};
export type FriendsTable = {
friends: Table<Friend>;
};
export const friendsSchema = {
friends: '++id, name, age'
};
Next, we update db/index.ts
to add our friends table.
// db/index.ts
import BaseDexie from 'dexie';
import { friendsSchema, FriendsTable } from './tables/friends';
type DexieTables = FriendsTable;
export type Dexie<T extends any = DexieTables> = BaseDexie & T;
export const db = new BaseDexie('j5bot') as Dexie;
const schema = Object.assign({}, friendsSchema);
db.version(1).stores(schema);
For every table we have, we implement a file according to the db/tables/friends.ts
pattern and then add the type and schema to db/index.ts
as follows.
// db/index.ts
import BaseDexie from 'dexie';
// import all of the table types and schemas
import { enemiesSchema, EnemiesTable } from './tables/enemies';
import {
familyMembersSchema,
FamilyMembersTable,
} from './tables/familyMembers';
import { friendsSchema, FriendsTable } from './tables/friends';
// add table types to union type
type DexieTables =
& EnemiesTable
& FamilyMembersTable
& FriendsTable;
export type Dexie<T extends any = DexieTables> = BaseDexie & T;
export const db = new BaseDexie('j5bot') as Dexie;
// add schemas to array
const schema = Object.assign({},
enemiesSchema,
familyMembersSchema,
friendsSchema,
);
db.version(1).stores(schema);
All in all, this should provide you with a type safe, compositional pattern for using Dexie with Typescript without using classes.