Home > Enterprise >  How to return type based on array fields type
How to return type based on array fields type

Time:08-17

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);
  }
  • Related