вообще-то можно. но вопрос это не простой ни разу.
в распоследнем тайпскрипте 3.4 появилась возможность поставить массиву модификатор
as const
, который сделает из него tuple с константами.
взяв с
typeof
его тип, от него можно будет с помощью
keyof
получить index type - объединение имён всех его полей, а потом взять от него типы самих полей квадратными скобкaми, и там будут все ваши строчки.
на другие строчки оно уже начнёт ругаться. проблема в том, что кроме строчек там будут ещё и все методы и свойства массива. от этого ругань получится невразумительная, и кроме строчек будет подходить, например, число - длина того массива. ну и функции из прототипа массива, хотя вы вряд ли станете их присваивать своим полям.
чтобы оставить только строки, придётся использовать ещё и conditional type (снова в сочетании с mapped и index types): опять получить полное объединение имён полей, пройти по всем полям, получить тип, и если это строка - взять имя поля, а если нет - взять
never
. и результат выбирать уже по отфильтрованному объединению имён полей - по never ничего не выбирается.
const x = ['значение1', 'значение2', 'значение3'] as const;
type AllValuesOfX = (typeof x)[keyof typeof x];
const tst1_1:AllValuesOfX = 'значение1';
const tst1_2:AllValuesOfX = 'значение4'; //error TS2322: Type '"значение4"' is not assignable to type '"значение1" | "значение2" | "значение3" | 3 | (() => string) | (() => string) | { (...items: ConcatArray<"значение1" | "значение2" | "значение3">[]): ("значение1" | "значение2" | "значение3")[]; (...items: ("значение1" | ... 2 more ... | ConcatArray<...>)[]): ("значение1" | ... 1 more ... | "значение3")[]; } | ... 1...'.
const tst1_3:AllValuesOfX = 3;
const tst1_4:AllValuesOfX = Array.prototype.map;
type StringProperties<T> = { [K in keyof T]: T[K] extends string ? K : never }[keyof T];
type StringsFromX = (typeof x)[keyof StringProperties<typeof x>];
const tst2_1:StringsFromX = 'значение2';
const tst2_2:StringsFromX = 3; // error TS2322: Type '3' is not assignable to type '"значение1" | "значение2" | "значение3"'.