Home > Enterprise >  Using types in a record to enforce its value in typescript
Using types in a record to enforce its value in typescript

Time:09-07

Given that I have the following types:

export type AnalyticsEventButtonClicked = {
  type: 'AnalyticsEventButtonClicked',
  payload: {
    label: string;
  }
};

export type AnalyticsEventTextChanged = {
  type: 'AnalyticsEventTextChanged',
  payload: {
    value: string;
  }
};

export type AnalyticsEvents = 
  | AnalyticsEventButtonClicked
  | AnalyticsEventTextChanged;

I want to be able to create a Record which will take both of these analytics events and specifically know what the payload should be based on its key. For example:

export const handleAnalytics: Record<AnalyticsEvents['type'], (???['payload']) => string> = {
  AnalyticsEventButtonClicked: ({ label }) => { return `Label: ${label}`; },
  AnalyticsEventTextChanged: ({ value }) => { return `Value: ${value}`; },
};

I am trying to find out what to replace ??? with in order to ensure the parameters of the anonymous callback function matches the payload that corresponds to the key in the record.

CodePudding user response:

Instead of a Record you will need to make the mapped type yourself so you can have access to the key being used:

export const handleAnalytics: {
    [K in AnalyticsEvents["type"]]: (params: Extract<AnalyticsEvents, { type: K }>["payload"]) => string;
}

We use Extract to get the member of the union whose type is K, then get their payload.

  • Related