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;
...
}
CodePudding user response:
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);
}