1

I have an array of the form

const arr = [
  { foo: 'a' },
  { foo: 'b' },
  ...
] as const;

One thing this lets me do is generate the union type 'a' | 'b' | ... with typeof arr[number]['foo']. However, if I want to get the array form of the union type (like String Union to string Array), there doesn't seem to be a good solution.

arr.map(({foo}) => foo)

is of type ('a' | 'b' | ...)[] instead of readonly ['a', 'b', ...]. How can I get the latter?

Simon Berens
  • 554
  • 4
  • 11
  • 1
    I guess it would be something like [this playground link](https://www.typescriptlang.org/play?#code/MYewdgzgLgBAhgJwTAvDA2gKBjA3jAMxBAC4YByOcmAXwBps9DizyAja+zAXXghlCQoAbkyYoATwAOAUxgBBJKhiTZIAvCSjVcgGLEA8gQA8AFQB8y0zBkAPKDLAATfviKkYASzAEZyAGq0MAD8MIFkYDIAbn7a0nrEishoSTb2ji5ePn4KIUzoANJZMADWMhLqCtxk+iBGxkmF3JY0MBHRsZhAA)? – spender Mar 14 '22 at 21:55
  • 2
    ...or [this playground link](https://www.typescriptlang.org/play?#code/MYewdgzgLgBAhgJwTAvDA2gKBjA3jAMxBAC4YByOcmAXwBps9DizyAja+zAXXghlCQoAbkyYoATwAOAUxgAxYgHkCAHgAqAPlQx1MGQA8oMsABN++IqRgBLMARnIAarRgB+GC7JgZAN0eikrIKxACCSKoAkqH6RibmMAgycKbgADYSTFZkAK5gANZgIADuYLTo3Npo0bHGZvx2DsgxHvjoANK2ZfkyEiAEMKHcZIogKqqhHZWu3n4B4tJySjlQUis6o+EIqkEy-fBImphAA) , which is a bit more type-safe imo. – spender Mar 14 '22 at 22:11
  • wow! now I'm curious, is it possible to actually generate an array that would have this type without typecasting? – Simon Berens Mar 15 '22 at 01:40
  • No, and that is by design. Mapping over an array returns a _new_ array, and TypeScript can't (and shouldn't) assume that the new array should _also_ be readonly. You have to cast it so explicitly. It can only infer what types will be in the array, not their ordinality or readonly status. That said, casting is fine if you are careful about it; it exists pretty much for scenarios like this among others. – jered Mar 15 '22 at 06:12

0 Answers0