Как сказать TypeScript, что мой аргумент функции является ключом Enum? - PullRequest
1 голос
/ 15 апреля 2020

У меня есть enum, который отображает статус HTTP на их код следующим образом:

enter image description here

Я легко могу получить эти коды, получив доступ к их ключам ( обратите внимание, как IntelliSense показывает HttpStatus.NOT_FOUND = 404 на правой панели)

enter image description here

Теперь, скажем, у меня есть функция с именем sendStatus:

Как я должен набрать эту функцию, чтобы эти коды автоматически заполнялись IntelliSense?

enter image description here

Использование keyof typeof не работает, потому что не выполняет автозаполнение значения перечисления.

Ответы [ 3 ]

5 голосов
/ 23 апреля 2020

То, что вы хотите, напрямую невозможно. Когда вы делаете keyof typeof, вы создаете тип объединения 'CREATED' | 'OK' | 'NOT_FOUND' ..., который полностью отделен от перечисления, которым он когда-то был.

Самое близкое, что вы можете получить, это сделать

function sendStatus(code: HttpStatus) {
    // code
}

send(HttpStatus.OK) // This will autocomplete and show the status code numbers

, а затем преобразование кода в строку внутри функции sendStatus.

Трудно сказать, чего вы на самом деле хотите, не зная точного использования, которое вы ищете, но я бы рассмотрел просто наличие простого старого объекта вместо enum

const HTTP_STATUS = {'OK':200, 'CREATED':201} as const

Затем, если вам нужно, вы также можете создать оба типа, например, так:

type StringStatus = keyof typeof HTTP_STATUS // 'OK' | 'CREATED'
type NumsStatus = (typeof HTTP_STATUS)[keyof typeof HTTP_STATUS] // 200 | 201

Как правило, редко есть веская причина для использования enum с в современном ТС. Обычно объекты и / или типы объединения делают работу намного лучше.

3 голосов
/ 18 апреля 2020

Просто чтобы подтвердить, keyof typeof не работает так, как вы хотите, ниже приведены скриншоты завершения кода Webstorm. Webstorm использует то же самое Языковая служба Typescript , как VS Код использует . Эта языковая служба предоставляет, помимо прочего, информацию о типе и завершение кода.

enter image description here enter image description here

2 голосов
/ 15 апреля 2020

Вы можете протестировать keyof typeof, запустив такой пример, который показывает, что само Enum отлично работает в вашем случае.

enum HttpStatus {
    OK = 200,
    CREATED = 201
}

function printStatus(code: keyof typeof HttpStatus) {
    const num = HttpStatus[code];
    if (num <= HttpStatus.CREATED) {
       console.log('HTTP Status key is: ', code);
       console.log('HTTP Status value is: ', num);
    }
}

printStatus("OK");

// Prints out
// > HTTP Status key is:  – "OK"
// > HTTP Status value is:  – 200
// Which shows that Enum value is being detected properly

keyof typeof возвращает тип, который представляет все ключи Enum в виде строки, и Вот почему автозаполнение ведет себя так. https://www.typescriptlang.org/docs/handbook/enums.html#enums -при-компиляции

...