1

Is there a way to define that an array ['left', 'center', 'right'] is not a string[] but Position[] in this code example without storing it in a variable:

type Position = 'left' | 'center' | 'right';

const sidePositions: Position[] = ['left', 'center', 'right'].filter(p => p !== 'center');

Example is a very simplified version of what we are actually doing in our project, we cannot use just ['left', 'right'] array instead. The following workaround works but we won't get a TS error if we mistype some words and that can cause some human errors:

const sidePositions: Position[] = (['foo', 'bar', 'right'] as Position[]).filter(p => p !== 'center');

Of course it is possible to store the array in a typed variable first, but in our case it is less convenient. Here's a link to TS Playground

Dmytro Garastovych
  • 335
  • 1
  • 2
  • 10
  • 1
    `([...] as const).filter(...)`? https://tsplay.dev/wep5EW – jonrsharpe Jul 25 '22 at 13:47
  • it is better than ```as Position[]``` because we get an error, but we still get an error not in the right place – Dmytro Garastovych Jul 25 '22 at 13:56
  • 1
    What do you mean "an error not in the right place"? Fundamentally it's all just working around the correct solution: assign the array to a typed variable first. – jonrsharpe Jul 25 '22 at 13:57
  • Array ```['foo', 'bar', 'right']``` should be marked as invalid because it should be of type ```Position[]``` and it is clearly not. Now we see that ```sidePositions``` variable is invalid which is correct, but it is a result of other array being invalid – Dmytro Garastovych Jul 25 '22 at 14:06
  • It suggests how to write a type but how should we specify that the created on the fly array is of a specific type? – Dmytro Garastovych Jul 25 '22 at 14:47
  • @johnsharpe's suggestion is a good one. The whole line is in error; it's a bit strange to insist that one particular part of it is the "right" place for the error. It's like saying that in `1 + 2 = 4` the error is specifically the `2` ("it should be `3`"). I mean, I guess you can think that, but someone else looking at it might reasonably say that it's the `4` ("it should be `5`") or `=` ("it should be `<`") etc etc. The compiler isn't human; it has to use heuristics for issuing errors, and the error here seems quite reasonable to me. – jcalz Jul 25 '22 at 19:16
  • 1
    It looks like you want the so-called `satisfies` operator as discussed in https://github.com/microsoft/TypeScript/issues/47920. If it existed, you could write `(['foo', 'bar', 'right'] satisfies Position[])` and it would check without asserting or widening. It doesn't currently exist in TS. See the answer to the linked question for more information and the current workarounds. – jcalz Jul 25 '22 at 19:23
  • That ```satisfies Position[]``` would be a perfect solution in this case, I would actually accept that as an answer to my question if I could – Dmytro Garastovych Jul 27 '22 at 08:09

0 Answers0