2

Is it possible to type the enum array in a way that forces it to contain every single value of the EPostFromField enum?

This is a mongodb schema, and the use case would be to future proof the enum field if more enums are added later on (ie: have the compiler throw an error because the array doesn't have all the enum values enumerated).

As a bonus I guess the next level would be a solution that also guarantees that the enum array values are unique :)

export const enum EPostFromField {
  Resident = 'resident',
  AdminUser = 'admin-user', // Admin <user name>
  BoardUser = 'board-user', // Board <user name>
  AdminSociety = 'admin-society', // Admin <community name>
  BoardSociety = 'board-society', // Board <community name>
}

showPostAs: {
    type: String,
    default: EPostFromField.Resident,
    enum: [
      EPostFromField.Resident,
      EPostFromField.AdminUser,
      EPostFromField.BoardUser,
      EPostFromField.AdminSociety,
      EPostFromField.BoardSociety,
    ] as EPostFromField[], // DEVNOTE: Improve typing to enforce *every* unique key of enum
  },
  • Possible duplicate of [Enforce that an array is exhaustive over a union type](https://stackoverflow.com/questions/55265679/enforce-that-an-array-is-exhaustive-over-a-union-type) – jcalz Jun 03 '20 at 00:28
  • 1
    enum objects, like all objects, have *keys* and *values* which are different. `"Resident"` is a *key*, but `EPostFromFileld.Resident` is its *value*. You talk about wanting to guarantee unique *keys*, but you are making an array of *values*. Are you using the word "key" when you mean "value"? If not, I'm confused; could you elaborate? – jcalz Jun 03 '20 at 00:31
  • @jcalz Yes. Sorry for mixup. The end goal is to have the mongodb enum field contain (and therefore only accept) values of enum EPostFromField. Thank you and I will edit the question. – Bryan Oliveira Jun 03 '20 at 15:41

1 Answers1

4

You could define a string enum and do the following:

enum EPostFromField {
    Resident = "Resident",
    AdminUser = "AdminUser",
    BoardUser = "BoardUser",
    AdminSociety = "AdminSociety",
    BoardSociety = "BoardSociety"
}

const epostFromFieldKeys = Object.keys(EPostFromField);

const epostFromFields = epostFromFieldKeys as EPostFromField[]

You can see this running in this playground link.

The values in the array would be unique if you define the string values in the enum uniquely(!).

Ben Smith
  • 19,589
  • 6
  • 65
  • 93
  • Thanks Ben! Yes, in effect this answers my question :) I was however searching for something a bit more condensed. Take the typescript `Partial` utility type, I was hoping for something more along these lines (but instead of a partial match, a complete + mandatory + unique match). – Bryan Oliveira Jun 08 '20 at 16:46