Вопрос:

Как я могу объявить Enum в TypeScript, который будет отображаться в глобальные свойства, определенные в среде?

javascript typescript enums

351 просмотра

2 ответа

457 Репутация автора

У меня есть среда с несколькими константами по всему миру:

TOP = 1
TOP_RIGHT = 2
RIGHT = 3
BOTTOM_RIGHT = 4
BOTTOM = 5
BOTTOM_LEFT = 6
LEFT = 7
TOP_LEFT = 8

Для меня ясно, что эти 8 констант являются не просто произвольными, а фактически набором направлений. Поэтому я хотел бы, чтобы они были такого DIRECTIONтипа, чтобы я мог делать такие вещи:

let test: DIRECTION = TOP_LEFT;

enumТипа , кажется наиболее логичным способом достичь этого, но я столкнулся со следующей проблемой:


Я пытался реализовать это поведение ранее, с некоторыми трудностями.

src/main.ts(1,23): error TS2304: Cannot find name 'TOP_LEFT'.

Файлы машинописи:

main.ts:

let test: DIRECTION = TOP_LEFT;
console.log(test);

direction.d.ts:

declare enum DIRECTION {
    TOP = 1,
    TOP_RIGHT = 2,
    RIGHT = 3,
    BOTTOM_RIGHT = 4,
    BOTTOM = 5,
    BOTTOM_LEFT = 6,
    LEFT = 7,
    TOP_LEFT = 8,
}

Игнорируя ошибку компиляции, результат выполнения tsc в JavaScript (он же транслируемый код) выглядит так, как будто он получит доступ к предопределенному глобальному свойству:

let test = TOP_LEFT;
console.log(test);

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

Автор: Stack Tracer Источник Размещён: 01.01.2018 10:20

Ответы (2)


1 плюс

2079 Репутация автора

Вы объявили окружающий enum: enums . Они обычно используются для предоставления информации о типе для уже существующего типа, например, определенного в импортированной библиотеке js. Если вы посмотрите на переданный код, то увидите, что он на самом деле не генерировал поиск любого типа.

Обычный способ объявить перечисление:

 enum DIRECTION {
    TOP = 1,
    TOP_RIGHT = 2,
    RIGHT = 3,
    BOTTOM_RIGHT = 4,
    BOTTOM = 5,
    BOTTOM_LEFT = 6,
    LEFT = 7,
    TOP_LEFT = 8,
}

который будет генерировать:

var DIRECTION;
(function (DIRECTION) {
    DIRECTION[DIRECTION["TOP"] = 1] = "TOP";
    DIRECTION[DIRECTION["TOP_RIGHT"] = 2] = "TOP_RIGHT";
    DIRECTION[DIRECTION["RIGHT"] = 3] = "RIGHT";
    DIRECTION[DIRECTION["BOTTOM_RIGHT"] = 4] = "BOTTOM_RIGHT";
    DIRECTION[DIRECTION["BOTTOM"] = 5] = "BOTTOM";
    DIRECTION[DIRECTION["BOTTOM_LEFT"] = 6] = "BOTTOM_LEFT";
    DIRECTION[DIRECTION["LEFT"] = 7] = "LEFT";
    DIRECTION[DIRECTION["TOP_LEFT"] = 8] = "TOP_LEFT";
})(DIRECTION || (DIRECTION = {}));

Вы бы тогда использовали это так:

const t: DIRECTION = DIRECTION.TOP_LEFT;
Автор: dashton Размещён: 01.01.2018 10:42

2 плюса

1836 Репутация автора

Решение

Вы неправильно интерпретируете использование перечислений. Enum не существует в Javascript таким же образом, как, например, c ++. Когда компилятор компилирует ваше объявление enum, на его месте создается новая переменная с отображениями для получения ключа и значения.

Следующее перечисление ...

enum Example {
    One,
    Two
}

... является эквивалентом TypeScript следующего объекта Javascript:

var Example;
(function (Example) {
    Example[Example["One"] = 0] = "One";
    Example[Example["Two"] = 1] = "Two";
})(Example || (Example = {}));

Похоже, что после этого вы получите набор констант, которые сопоставлены с типом. Вы можете объявить литеральные типы в TypeScript. например declare type Direction = 1 | 2 | 3 ... | 8;. Однако это не очень полезно, когда вы реорганизуете код или добавляете больше констант направления. К счастью, вы можете использовать typeofключевое слово, чтобы получить значения объекта. Вы можете объявить свой Directionsтип следующим образом:

const TOP = 1
const TOP_RIGHT = 2
const RIGHT = 3
const BOTTOM_RIGHT = 4
const BOTTOM = 5
const BOTTOM_LEFT = 6
const LEFT = 7
const TOP_LEFT = 8

declare type Direction =
    typeof TOP |
    typeof TOP_RIGHT |
    typeof RIGHT |
    typeof BOTTOM_RIGHT |
    typeof BOTTOM |
    typeof BOTTOM_LEFT |
    typeof LEFT |
    typeof TOP_LEFT;

const dir: Direction = TOP_LEFT; // or = 8

Переменные, объявленные с этим типом, Directionдолжны иметь значение, совпадающее с типом, например, в вашем случае с 1 по 8.

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

Автор: Shane van den Bogaard Размещён: 01.01.2018 11:31
Вопросы из категории :
32x32