TypeScript Условные типы и typeof - PullRequest
0 голосов
/ 04 декабря 2018

Итак, у меня есть этот код, который проверяет, который создает AnyOfTheAbove type из числа string констант:

const IT_COULD_BE_THIS = 'something';
const OR_THAT = 'something else';
const OR_EVEN = 'the other thing';

export type AnyOfTheAbove =
    | typeof IT_COULD_BE_THIS 
    | typeof OR_THAT 
    | typeof OR_EVEN;

Я бы очень хотел написать

export type AnyOfTheAbove = GetTypeof<
    | IT_COULD_BE_THIS 
    | OR_THAT 
    | OR_EVEN
>;

или аналогичные.У меня есть ощущение, что я могу сделать это с помощью условных типов.Но все мои попытки пока сгорели в огне.Это выполнимо?

1 Ответ

0 голосов
/ 04 декабря 2018

Это невозможно , поскольку тип не принимает объект времени выполнения, которому не предшествует typeof.(за исключением классов и перечислений)

Если вы действительно не пишете typeof для каждого объекта , вы можете обернуть все объекты в вызове функции , затем извлечение типов один раз с использованием typeof:

Использование поддельной функции

// No value produced at runtime, but infers union type statically
function unionType<T>(...arr: T[]): T { return null as unknown as T }

const IT_COULD_BE_THIS = 'something'
const OR_THAT = 'something else'
const OR_EVEN = 'the other thing'

// Extract types from function call
type AnyOfTheAbove = typeof AnyOfTheAbove
const AnyOfTheAbove = unionType(
  IT_COULD_BE_THIS,
  OR_THAT,
  OR_EVEN
)

Что подразумевает вызов времени выполнения (которыйпросто вернет null), но позволяет обойти ограничение.

Использование Tuple

// You need to specify `string` to infer each string correctly:
// https://github.com/Microsoft/TypeScript/issues/26158
function tuple<T extends string[]>(...t: T) { return t }

const IT_COULD_BE_THIS = 'something'
const OR_THAT = 'something else'
const OR_EVEN = 'the other thing'

// Extract types from function call
type AnyOfTheAbove = typeof AllOfTheAbove[number]
const AllOfTheAbove = tuple(
    IT_COULD_BE_THIS,
    OR_THAT,
    OR_EVEN
)

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

Ни один из них действительно не сохраняет символы и не упрощает читаемость.


Редактировать 26/08/2019

Использование Enum

Если вы можете определить все эти строки в перечислении, вы можете сделать:

enum AllEnum {
  IT_COULD_BE_THIS,
  OR_THAT,
  OR_EVEN,
}

// Static type
type All = keyof typeof AllEnum

// Access all strings at runtime
const allAtRuntime = Object.keys(AllEnum)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...