1

I want to do something like this:


type A = "A" | "B" | "C"; 

type ArrayofA = //???

const arr1 : ArrayofA = ["A", "B", "C"]; //ok
const arr2 : ArrayofA = ["A", "B"]; // not ok
const arr3 : ArrayofA = ["A", "B", "C", "D"]; //not ok

How can I do this?

dwjohnston
  • 11,163
  • 32
  • 99
  • 194

3 Answers3

1

There is a problem with the premise. That is that unions are unsorted, but arrays are sorted. "A" | "B" is equivalent to "B" | "A" but ["A", "B"] is not equivalent with ["B", "A"].

Because of this the mapping works easier the other way:

type ArrayofA = ["A", "B", "C"];

type A = ArrayofA[number];

const arr1: ArrayofA = ["A", "B", "C"]; //ok
const arr2: ArrayofA = ["A", "B"]; // not ok
const arr3: ArrayofA = ["A", "B", "C", "D"]; //not ok
Tiberiu Maran
  • 1,983
  • 16
  • 23
0

Use the const assertion introduced in TypeScript 3.4.

Elaborating from this answer it should be like:

const atype = [["A", "B", "C"]] as const;

type A_B_C = typeof atype[0][number]; // "A" | "B" | "C"
type Arrayof_A_B_C = typeof atype[number]; // ["A" | "B" | "C"]

const v: Arrayof_A_B_C = ["A", "B", "C"]; // OK
const w: Arrayof_A_B_C = ["A", "B"]; // not OK

const b: A_B_C = "B"; // OK
const d: A_B_C = "D"; // not OK
attdona
  • 17,196
  • 7
  • 49
  • 60
-1

What you're looking for is a tuple. The downside is it must be declared explicitly, so there aren't any handy shortcuts with type aliases or destructuring that I'm aware of.

type A = "A" | "B" | "C";

type ArrayofA = ["A", "B", "C"];

const arr1: ArrayofA = ["A", "B", "C"]; //ok
const arr2: ArrayofA = ["A", "B"]; // not ok
const arr3: ArrayofA = ["A", "B", "C", "D"]; //not ok
jered
  • 11,220
  • 2
  • 23
  • 34