Marcin
Marcin

Reputation: 600

Type from two objects with common keys and values of one of them

Given types:


type OrganizationFieldsToGet = { [key in keyof Organization]?: boolean };

type Organization = {
  id: string;
  name: string;
  displayName: string;
  pluginData?: string[];
  billableMemberCount: number;
  desc: string;
  descData: string | null;
  idBoards: string[];
  invitations: any[];
  invited: boolean;
  logoHash: string;
  memberships: string[];
  powerUps: number[];
  prefs: string;
  premiumFeatures: string[];
  products: number[];
  url: string;
  website: string;
};


type GetOrganization = <T extends OrganizationFieldsToGet>(idOrganization: string, fieldsToGet: T) => Promise<TheTypeToReturn<T>>

I would like to construct type of which keys come from object of type OrganizationFieldsToGet that has been passed to my function but which values are inherited from Organization.

meaning that if object {id: true} was passed to my function the return type should equal to {id: string}

I was thinking of something along the lines:


type TheTypeToReturn<T extends OrganizationFieldsToGet> = {[key in keyof T]: ??}

Upvotes: 0

Views: 350

Answers (1)

Maciej Sikora
Maciej Sikora

Reputation: 20132

type TheTypeToReturn<
T extends OrganizationFieldsToGet, 
_Keys extends keyof Organization = {
    [K in keyof T]: T[K] extends true ? K extends keyof Organization ? K : never : never
}[keyof T]> = Pick<Organization, _Keys>
// test
type Result = TheTypeToReturn<{displayName: true, logoHash: true}>
/*
type Result = {
    displayName: string;
    logoHash: string;
}
*/

Explanation:

  • _Keys - local type variable which picks keys if they have value true
  • T[K] extends true ? K extends keyof Organization ? K : never : never - this exactly line checks if our value is true, if so it puts key as a value type
  • [keyof T] we take all value types as a union (it will skip never)
  • Pick<Organization, _Keys> - use utility type Pick for evaluated keys

Upvotes: 3

Related Questions