TypeScript dynamically pick matching key-value pairs of an interface

38 views Asked by At

I am using following generic interface to select matching key-value pair types of an interface:

interface DefaultParams<T> {
  screen: keyof T;
  params?: T[keyof T];
}

and I want to use it with this navigation types so that I can pass respectively matching values in my navigate function:

export type RootTabParamList = {
  Home: undefined | DefaultParams<HomeTabStackParamList>;
  Health: undefined | DefaultParams<HealthTabStackParamList>;
};

export enum TenetCodes {
  Energy = "Energy",
  Sleep = "Sleep",
}

export type HomeTabStackParamList = {
  Dashboard: { tab: 'feed' | 'recommended' };
  Activity: undefined;
}

export type HealthTabStackParamList = {
  HealthScreen: undefined;
  SystemsList: undefined;
  SystemDetailsScreen: {
    tenetCode: TenetCodes;
    tenetResult?: string;
  };
  SampleSummaryScreen: {
    range?: Range;
    tenetCode: TenetCodes;
    sampleCode: string;
  };
};

But it allows me to use both HomeTabStackParamList and HealthTabStackParamList interchangeably between Home and Health keys

1

There are 1 answers

0
ankushlokhande On

If you want a strict type check for the screen and params keys based on the corresponding keys in the RootTabParamList, you can achieve this by following modification in DefaultParams interface:

type ScreenParams<T> = T extends { [key: string]: any }
  ? DefaultParams<{ screen: keyof T; params?: T[keyof T] }>
  : never;

export type RootTabParamList = {
  Home: undefined | ScreenParams<HomeTabStackParamList>;
  Health: undefined | ScreenParams<HealthTabStackParamList>;
};