I'm using Knex.js with TypeScript for database access.
Table
- uid (UUID, auto-generated by Postgres)
- name (varchar)
Model
interface User {
uid: string | null;
name: string;
}
Repository
class UserRepository {
public async insert(user: User): Promise<void> {
await knex('user').insert(user);
}
}
Usage
function someRouteHandler(req, res) {
const repo = new UserRepository(...)
// Next line will error out due to the object literal
// not having the uid property
repo.insert({
//uid: null // satisfies interface constraint but errors during insert
name: req.body.name,
});
}
Problem
The only way I see this working is to modify the repository class methods to explicitly say which fields I need to insert:
public async insert(user: User): Promise<void> {
await knex('user').insert({
name: user.name,
});
}
Unfortunately, this adds maintenance efforts since every time I modify the model I also need to modify the methods that do the queries to reflect the changed properties.
Is there a cleaner way of doing this?
uid
you're populating the property with? If it's a UUID, you could generate the UUID in the application layer and pass the value to theinsert
method, instead of passingnull
.undefined
instead ofnull
? In any case, as far as I can tell this has nothing to do with TS itself, it's a quirk of the library