Home > Net >  How to create a Record<> (or other mapping) in TypeScript keyed to an enum as a union
How to create a Record<> (or other mapping) in TypeScript keyed to an enum as a union

Time:02-15

I need to create function maps keyed to an enum, but if I use the Record<> utility type, it seems that it's requiring all of the enum values to exist in the mapping object. I need them to all be optional. For example:

enum ContentType {
  Text,
  Image,
  Video,
}
type MapFn = (value: string) => string;

type ContentTypeMap = Record<ContentType, MapFn>;

const myMap = {
  [ContentType.Text] : (value:string) => (value.toUpperCase),
} as ContentTypeMap;

Results in:

Conversion of type '{ 0: (value: string) => () => string; }' to type 'ContentTypeMap' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type '{ 0: (value: string) => () => string; }' is missing the following properties from type 'ContentTypeMap': 1, 2

I also tried simply:

type ContentMap = { [ContentType]: MapFn };

But the compiler complains about the use of ContentType:

A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.

I would think that enums count as literals, but I guess not in this case?

What can I use to create a map of (enum) => (function) where the object does not require all enum values to be implemented?

CodePudding user response:

I also tried simply:

type ContentMap = { [ContentType]: MapFn };

You're close, but it needs to be like this:

type ContentMap = { [key in ContentType]: MapFn };

And then to make them optional:

type ContentMap = { [key in ContentType]?: MapFn };

Playground link

If you prefer to use the Record notation, you can use the utility type Partial to make all its properties optional:

type ContentMap = Partial<Record<ContentType, MapFn>>;

Playground Link

  • Related