const record = await OrderModel.read(1003, [
'id',
'billing_name',
]);
##record type object should provide record.id or record.billing_name only
the OrderModel class already has a generic OrderType (T) with all the fields available in that table.
What I’m trying to do is infer the type of record with only the keys defined in the second argument (fields).
Currently, all keys of OrderType are available and I can’t seem to implement the Pick utility correctly to get the correct type returned.
// from OrderModel.ts
public async read(id: number, fields: (keyof T)[] = [])
{
const result = await this.database.read<T, typeof fields>(id, this.tableName, fields);
return result;
}
// from database adaptor (this.database above)
public async read<T, K extends (keyof T)>(id: number, tableName: string, fields: K[]): Promise<Pick<T, K>>
{
return this.connection(tableName).select(fields).where('id', id).first();
}
// OrderType
export interface OrderModel {
id: number;
billing_name: string;
billing_email: string;
...
}
>Solution :
You should apply the same generic type logic as your adapter read method, in the OrderModel version. Try something like this:
// notice generic and argument here, as well as return type
public async read<K extends keyof T>(id: number, fields: K[] = []): Promise<Pick<T, K>>
{
// notice type change below
const result = await this.database.read<T, K>(id, this.tableName, fields);
return result;
}
See example here, I had to make some changes in order not to implement all the classes, but the gist is the same
Side note: Since you are directly passing the promise, no need to return/await it separately, just return it immediately:
public async read<K extends keyof T>(id: number, fields: K[] = []): Promise<Pick<T, K>>
{
return this.database.read<T, K>(id, this.tableName, fields);
}