Есть ли в настоящее время способ конкатенации двух или более типов строковых литералов в один тип строкового литерала в TypeScript прямо сейчас?

avatar
Dudeonyx
23 января 2019 в 19:53
8967
3
32

Прежде всего, позвольте мне пояснить, что я ищу не тип объединения, а прямую конкатенацию, т.е. "Hel" + "lo" = "Hello", но для типов строковых литералов

По сути, у меня есть функция, которая принимает два строковых литерала, namespace и name, и объединяет их с / между ними в качестве вывода, но я не могу найти способ сделать вывод строковый литерал, а не общая строка.

Мне нужно, чтобы это был строковый литерал, потому что вывод будет использоваться как ключ объекта.

Я пробовал пересечения типов (&), +, .concat()

function makeKey<NS extends string, N extends string>(namespace: NS, name: N) {
    return namespace + '/' + name; // <- want this to be `NS + / + N` = `NS/N`
}
// I want this to return a string literal rather than a generic string

const objKey = makeKey('admin', 'home')
// I want typeof objKey to be a string literal: `"admin/home"`, not a generic `string`

typeof objKey является общим string, но я хочу, чтобы это был string literal "admin/home"

Источник
juanpa.arrivillaga
23 января 2019 в 19:59
0

Является ли строковый литерал отдельным типом в машинописном тексте?

Dudeonyx
23 января 2019 в 20:00
0

это подмножество типа string, более или менее то же самое, что и string Enums

Titian Cernicova-Dragomir
23 января 2019 в 20:01
1

Нет, нет текущего способа сделать это

jcalz
23 января 2019 в 20:02
2

Ответ, к сожалению, нет. Есть несколько предложений, которые могут дать вам эту функциональность (это или это), но я не думаю, что они рассматриваются.

Dudeonyx
23 января 2019 в 20:06
0

Литерал шаблона @GetOffMyLawn — это разные вещи, строковые литералы — это тип машинописного текста.

Ответы (3)

avatar
jcalz
1 августа 2019 в 01:23
35

TS4.1+ ответ:

Теперь вы можете использовать литеральные типы шаблонов, чтобы сделать следующее:

function makeKey<NS extends string, N extends string>(namespace: NS, name: N) {
    return namespace + '/' + name as `${NS}/${N}`
}

const objKey = makeKey('admin', 'home');
// const objKey: "admin/home"

Ссылка на игровую площадку


Ответ до TS4.1:

Ответ, к сожалению, нет. В GitHub есть несколько предложений по функциям, которые, если они будут реализованы, могут предоставить вам такие функции (microsoft/TypeScript#12754 для расширения ключей во время отображения типов или microsoft/TypeScript#6579 для манипулировать строковыми типами с помощью регулярных выражений), но я не думаю, что над ними ведется активная работа. Во всяком случае, я ничего не вижу в дорожной карте об этом. Если вы действительно хотите, чтобы это произошло, вы можете перейти к одной из этих проблем GitHub и дать им ???? или опишите свой вариант использования, если он особенно убедителен. Но я бы не стал задерживать дыхание. Извините!

mesqueeb
21 марта 2020 в 23:24
0

Спасибо @jcalz! Я пошел дальше и оставил комментарий в одной из тем с моим вариантом использования.

Jan Paepke
11 февраля 2021 в 14:07
0

Я не знал, что это вещь. очень круто, спасибо.

avatar
Aleksey L.
1 сентября 2020 в 07:33
4

Это станет возможным, как только типы строк шаблона будут выпущены (выглядит как в машинописном тексте 4.1):

function makeKey<NS extends string, N extends string>(namespace: NS, name: N) {
    return (namespace + '/' + name) as `${NS}/${N}`;
}

const objKey = makeKey('admin', 'home') // objKey is of type 'admin/home'

Детская площадка


Шаблонные строковые типы являются эквивалентом шаблонных строковых выражений в пространстве типов. Подобно строковым выражениям шаблона, типы строк шаблона заключены в разделители обратной кавычки и могут содержать заполнители формы ${T}, где T — это тип, который можно присвоить string, number, boolean или bigint. Строковые типы шаблонов обеспечивают возможность конкатенации литеральных строк, преобразования литералов нестроковых типов-примитивов в их строковое представление и изменения регистра или регистра строковых литералов. Кроме того, посредством вывода типов шаблонные строковые типы обеспечивают простую форму сопоставления строковых шаблонов и декомпозиции.

Некоторые примеры:

type EventName<T extends string> = `${T}Changed`;
type Concat<S1 extends string, S2 extends string> = `${S1}${S2}`;
type T0 = EventName<'foo'>;  // 'fooChanged'
type T1 = EventName<'foo' | 'bar' | 'baz'>;  // 'fooChanged' | 'barChanged' | 'bazChanged'
type T2 = Concat<'Hello', 'World'>;  // 'HelloWorld'
type T3 = `${'top' | 'bottom'}-${'left' | 'right'}`;  // 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'

Подробнее и примеры здесь

avatar
juminet
9 января 2020 в 08:54
-5

У меня это сработало с typescript 3.7.2, используя литерал шаблона для конкатенации и ключевое слово as для указания типа вывода моей функции.

const addSuffixToMyStringLiteral =
    (m: MyStringLiteral, suffix: string) => `${m}${suffix}` as MyStringLiteral;

Я не знаю, новая ли это функция машинописного текста или нет.

MistyK
25 января 2020 в 20:30
0

Тип ответа MyStringLiteral. Ожидается OP, например, literalexamplesuffix.