Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: How do I properly type an array composed of n N-tuples and m M-tuples?

Tags:

typescript

//An N-tuple (quadruple?) that is a subset of a row
type Quadruple = [string, string, number, boolean];

//A value that is a subset of a row
type Value = [string];

//A row in the format [...Quadruple[], ...Value[]]
type Row = (string | boolean | number)[]; //this works...but information is lost.

const egRow1: Row = ["id", "name", 1, true, "id2", "name2", 1, true, "id3", "name3", 1, false, "value1", "value2"];
const egRow2: Row = ["id", "name", 1, true, "id2", "name2", 1, true, "value1", "value2"];
const egRow3: Row = ["id", "name", 1, true, "value1", "value2"];

How can I type a row effectively to encode the fact that it is composed of M Quadruples followed by N Values?

like image 393
iflp Avatar asked Jul 29 '20 08:07

iflp


2 Answers

It seems to me that this can only be done by enumerating all possible quantities (M) of Quadruple and union these types:

type Row1 = [string, string, number, boolean, ...Array<string>];
type Row2 = [string, string, number, boolean, string, string, number, boolean, ...Array<string>];
type Row3 = [string, string, number, boolean, string, string, number, boolean, string, string, number, boolean, ...Array<string>];
...
type RowM = [string, string, number, boolean, ..., ...Array<string>];

type Row = Row1 | Row2 | Row3  | ... | RowM;

Playground

like image 200
Nikita Madeev Avatar answered Nov 14 '22 18:11

Nikita Madeev


In typescript 4.0 you can use Variadic Tuple Types PR to make the syntax a bit simpler, but you still need to define up to a specific number of items:

type Quadruple = [string, string, number, boolean];
type Value = string;

type Row = [
    ...([] | Quadruple),
    ...([] | Quadruple),
    ...([] | Quadruple),
    ...([] | Quadruple),
    ...([] | Quadruple),
    ...([] | Quadruple),
    ...([] | Quadruple),
    ...Value[]
]

const egRow1: Row = ["id", "name", 1, true, "id2", "name2", 1, true, "id3", "name3", 1, false, "value1", "value2"];
const egRow2: Row = ["id", "name", 1, true, "id2", "name2", 1, true, "value1", "value2"];
const egRow3: Row = ["id", "name", 1, true, "value1", "value2"];

Playground Link

like image 2
Titian Cernicova-Dragomir Avatar answered Nov 14 '22 18:11

Titian Cernicova-Dragomir