Home > Enterprise >  Typescript: Use keyof value in adjacent property type
Typescript: Use keyof value in adjacent property type

Time:09-26

I have a dynamic navigation stack like this:

const fullKYCStack = [
  {
    name: 'Account Credentials Screen',
    component: AccountCredentialsScreen,
  },
  {
    name: 'Verify Email Screen',
    component: VerifyEmailScreen,
  },
  ...
}

There is an object of possible names:

type KYCStackParamList = {
  'Account Credentials Screen': undefined;
  'Verify Email Screen': undefined;
  ...
};

I would like to create a type such that each item in the array is typed according to the "name" that is used, so the first item in the array would have this type:

type AccountCredentialsScreen = {
  name: 'Account Credentials Screen';
  component: (
    props: NativeStackScreenProps<KYCStackParamList, 'Account Credentials Screen'>,
  ) => JSX.Element;
}

I tried to make a generic type for each item:

interface KYCScreen<K extends keyof KYCStackParamList> {
  name: K;
  component: (
    props: NativeStackScreenProps<KYCStackParamList, K>,
  ) => JSX.Element;
}

However sadly the generic isn't inferred when applying it to the array:

const fullKYCStack: KYCScreen[] = [
  {
    name: 'Account Credentials Screen',
    component: AccountCredentialsScreen,
  },
  {
    name: 'Verify Email Screen',
    component: VerifyEmailScreen,
  },
  ...
}

Gives: "Generic type 'KYCScreen' requires 1 type argument(s).ts(2314)"

How can I tell Typescript to get this type value from the "name" property for each item?

CodePudding user response:

It is not really possible create a generic type where you don't have to specify an explicit type when using like this. The alternative would be to compute a union type of all possible combinations.

type KYCScreen = {
  [K in keyof KYCStackParamList]: {
    name: K,
    component: (
      props: NativeStackScreenProps<KYCStackParamList, K>,
    ) => JSX.Element;
  }
}[keyof KYCStackParamList]

Playground

  • Related