0

I have the following type and interface:

import { FC } from 'react';

export type RuleType =
  | 'userId'
  | 'userSegment'
  | 'userBasketItem'
  | 'userPurchases'
  | 'lastPurchaseDate'
  | 'userPurchasedItem'
  | 'userPurchasedGroup'
  | 'allUsers';

interface RuleInputs {
  userId: FC;
  userSegment: FC;
  userBasketItem: FC;
  userPurchases: FC;
  lastPurchaseDate: FC;
  userPurchasedItem: FC;
  userPurchasedGroup: FC;
  allUsers: FC;
}

Instead of typing every key for RuleInputs by hand I would like it to be added dynamically when new values are added to the RuleType union. Is there a way to do this using Typescript or do I need to update both types when RuleType changes?

1 Answer 1

2

You can use mapped types to achieve your desired behavior:

import { FC } from 'react';

export type RuleType =
  | 'userId'
  | 'userSegment'
  | 'userBasketItem'
  | 'userPurchases'
  | 'lastPurchaseDate'
  | 'userPurchasedItem'
  | 'userPurchasedGroup'
  | 'allUsers';

type RuleInputs = {
  [R in RuleType] : FC
}

I also whant to show an example, where the type is used directly as an type annotation. Maybe you dont need an explicit named type/interface when its just used for one variable.

const anyVar: { [P in RuleType] : FC } = { /** content here */ }

Advanced ussage

Filter out some RuleType

// filter out 'userId' and 'userEegment'
type RuleInputs = {
  [R in RuleType] : R extends 'userId' | 'userSegment' ? never : FC
}

Assign different types to specific RuleType

type RuleInputs = {
  [R in RuleType] : R extends 'userId' | 'userSegment' ? AnyType : FC
}

Mix different conditions for specific RuleType

type RuleInputs = {
  [R in RuleType] : 
    R extends 'userId' | 'userSegment' ? never :
    R extends 'userBasketItem' ? any : 
    FC
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.