Home > Mobile >  Typescript Union Types: Type Names as object members
Typescript Union Types: Type Names as object members

Time:02-02

Is there a way to extract the names of types so I can use them as Keys in a Type definition?

type O1 = {…}
type O2 = {…}
type O3 = {…}
type Item = O1 | O2 | O3;

type ItemCalculator = {
  [key: string]: Function
} // how can I enforce key to be either "O1" or "O2" or "O3"

CodePudding user response:

You can't directly do something like this

type ItemCalculator = {
  [key: Item]: Function
}

because you will end up with an exception "An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead"

But you can use mapped object as suggested.

In a simplified example:

type Item = "O1" | "O2" | "O3";

type ItemCalculator = {
  [I in Item]: Function;
};

const itemCalculator: ItemCalculator = {
  O1: () => {}, // OK
  O2: () => {}, // OK
  O3: () => {}, // OK
  O4: () => {}, // typescript error ts(2322)
};

To answer the comment of @michael

Any chance I can infer these strings dynamically? Currently I a have some automatically generated definitions from a backend

Yes. Using Generic Types. But you will need to know in advance what type of object you will received.

e.g

type ItemCalculator<Type> = {
  [T in keyof Type]: Function;
};

type ApiResponse = {
  name: string;
  id: string;
};

const itemCalculator: ItemCalculator<ApiResponse> = {
  name: (item: ApiResponse) => item.name,
  id: (item: ApiResponse) => item.id,
};
  •  Tags:  
  • Related