Dictionary keys as acceptable property values

Viewed 44

I have created such a dictionary:

const iconTypesDictionary: { [key: string]: IconPrefix } = {
  solid: 'fas',
  regular: 'far',
  light: 'fal',
}

And I would like to use the keys of this dictionary as possible values for the property. So to replace the repeated keys in this case:

export interface IconProps {
   type?: 'solid' | 'regular' | 'light';
}

Is there a solution for this?

1 Answers

Until the time that we get satisfies in TS (see ms/TS#47920 and ms/TS#46827, etc.), you can use a constrained identity function to ensure that the dictionary you define conforms to the type that you expect, while also preserving its type information. After creating the object value, you only need to use keyof typeof value to get a type which represents its keys:

TS Playground

// You didn't share this type so I am using this as an example:
type IconPrefix = 'fal' | 'far' | 'fas';

// Using this function allows you to constrain an argument value's type,
// while also preserving its actual type information:
function createConstrainedIdFn <T>(): <Value extends T>(value: Value) => Value {
  return value => value;
}

// Use it like this:
// (note the double invocation and that the value argument goes in the second parentheses)
const iconTypesDictionary = createConstrainedIdFn<Record<string, IconPrefix>>()({
  solid: 'fas',
  regular: 'far',
  light: 'fal',
}); /* type is:
{
  solid: "fas";
  regular: "far";
  light: "fal";
}
*/

type IconTypesDictKey = keyof typeof iconTypesDictionary; // "solid" | "regular" | "light"

type IconProps = {
  type?: IconTypesDictKey;
};

Related