Reputation: 1581
I have my types generated for pg database via kysley-codegen
and it generates this interface for my QuestionReview table:
export interface QuestionReview {
id: Generated<number>; // this will be a problem
idQuestion: number;
idUserReviewed: number;
tsCreated: Timestamp; // this will be a problem
tsModified: Timestamp; // this will be a problem
userModified: string;
}
Now, in my service class I'm inserting into this table and want to return the newly inserted entity as Promise<QuestionReview>
.
Here is the code:
const rv = await this.db
.insertInto('questionReview')
.values({
idQuestion: idQuestion,
idUserReviewed: idAppUser,
} as Insertable<QuestionReview>)
.returningAll()
.executeTakeFirstOrThrow();
which returns the rv object with these JS types:
{
id: number,
...
tsCreated: Date,
tsModified: Date
}
I can not just return this object because TS cannot cast:
I've ended up returning this rather humiliating object with brute-force casting:
return {
...rv,
id: rv.id as unknown as Generated<number>,
tsCreated: rv.tsCreated as unknown as Timestamp,
tsModified: rv.tsModified as unknown as Timestamp,
};
What am I doing wrong, is there a better way to return strongly typed inserted entity?
Upvotes: 0
Views: 95
Reputation: 25976
Use the use the Selectable
, Insertable
and Updateable
wrappers.
Consult the Kysely docs:
// You should not use the table schema interfaces directly. Instead, you should
// use the `Selectable`, `Insertable` and `Updateable` wrappers. These wrappers
// make sure that the correct types are used in each operation.
//
// Most of the time you should trust the type inference and not use explicit
// types at all. These types can be useful when typing function arguments.
export type Person = Selectable<PersonTable>
export type NewPerson = Insertable<PersonTable>
export type PersonUpdate = Updateable<PersonTable>
In your case:
import {
ColumnType,
Generated,
Insertable,
JSONColumnType,
Selectable,
Updateable,
} from 'kysely'
// Generated
export type Timestamp = ColumnType<Date, Date | string, Date | string>;
// Generated
export interface QuestionReview {
id: Generated<number>; // this will be a problem
idQuestion: number;
idUserReviewed: number;
tsCreated: Timestamp; // this will be a problem
tsModified: Timestamp; // this will be a problem
userModified: string;
}
export type QuestionReviewSelectable = Selectable<QuestionReview>
QuestionReviewSelectable
is inferred to:
type QuestionReviewSelectable = {
id: number;
idQuestion: number;
idUserReviewed: number;
tsCreated: Date;
tsModified: Date;
userModified: string;
}
Upvotes: 1