Ilijanovic
Ilijanovic

Reputation: 14924

Get type from nested object as type

Is it possible to get only the number keys as an type?

export const messageTypes = {
  ABLEHNUNG_ECON: {
    56: {
      message: "Zählpunkt nicht gefunden",
      event: function () {},
    },
    181: {
      message: "Gemeinschafts-ID nicht vorhanden",
      event: function () {},
    },
  },
  ZUSTIMMUNG_ECON: {
    175: {
      message: "Zustimmung erteilt",
      event: function () {},
    },
  },
  ANTWORT_ECON: {
    99: {
      message: "Meldung erhalten",
      event: function () {},
    },
  },
  ABSCHLUSS_ECON: {
    message: "Abschluss erhalten",
    event: async function (userId: string) {
      await sendNotification(userId, this.message);
    },
  },
};

If i do type MessageT = typeof messageTypes i get the whole object, but is it somehow possible to get only the numbers?

Result should be: type ResponseCodesT = 56 | 181 | 175 | 99

Upvotes: 0

Views: 57

Answers (1)

Clashsoft
Clashsoft

Reputation: 11882

It is possible using a little keyof trick (Typescript: keyof typeof union between object and primitive is always never):

export const messageTypes = {
  ABLEHNUNG_ECON: {
    56: {
      message: "Zählpunkt nicht gefunden",
      event: function () {},
    },
    181: {
      message: "Gemeinschafts-ID nicht vorhanden",
      event: function () {},
    },
  },
  ZUSTIMMUNG_ECON: {
    175: {
      message: "Zustimmung erteilt",
      event: function () {},
    },
  },
  ANTWORT_ECON: {
    99: {
      message: "Meldung erhalten",
      event: function () {},
    },
  },
};

type AllUnionMemberKeys<T> = T extends any ? keyof T : never;
type MessageCode = AllUnionMemberKeys<(typeof messageTypes)[keyof typeof messageTypes]>;

// type MessageCode = 56 | 181 | 175 | 99

Playground

I intentionally left out ABSCHLUSS_ECON as an exercise for the reader :) (Hint: the union will include message and event).

Upvotes: 2

Related Questions