Я не думаю, что вы можете программно сделать префикс, чтобы система типов понимала его;для этого потребуются некоторые операции type , которые еще не являются частью языка.Существует существующее предложение для этой функции, но похоже, что никто не работает над ней.
Что касается получения ключа и значения, которые должны быть точно такими жеВы можете написать функцию, которая берет список строк и создает карту типа enum со строгой типизацией:
function enumize<K extends string>(...args: K[]): {[P in K]: P} {
const ret = {} as {[P in K]: P};
args.forEach(k => ret[k]=k);
return ret;
}
const Cmd = enumize("StartServer", "StopServer", "ResumeServer1", "ResumeServer2");
Признается, что значение Cmd
имеет тип { StartServer: "StartServer"; ... }
.Вы сможете получить доступ к элементам, как и ожидалось:
console.log(Cmd.StartServer); // works
Официальный enum
также создает несколько именованных типов , которых enumize()
нет.Чтобы полностью воспроизвести типы, вам нужно проделать дополнительную работу:
type Cmd = keyof typeof Cmd; // allows you to refer to the type Cmd as before
Это тип объединения, упомянутый в ответе @ RobbyCornelissen.Вам это нужно, если вы собираетесь ссылаться на Cmd
как на тип, например:
declare function requireCmd(cmd: Cmd); // the Cmd here is a type
requireCmd(Cmd.StopServer); // works
Если вам нужно сослаться на типы каждого элемента enum, вам придется выполнять еще большую работувключая уродливое дублирование кода:
namespace Cmd {
export type StartServer = typeof Cmd.StartServer
export type StopServer = typeof Cmd.StopServer
export type ResumeServer1 = typeof Cmd.ResumeServer1
export type ResumeServer2 = typeof Cmd.ResumeServer2
}
Этот материал понадобится для ссылки на такие типы, как Cmd.StopServer
, например:
interface CommandInfo {
kind: Cmd;
}
interface StopServerInfo extends CommandInfo {
kind: Cmd.StopServer; // need namespace for this line
commandIssueDate: Date;
numberOfUsersForcedOffline: number;
}
Но если вы не собираетесь этого делатьочень много, тогда вы можете пропустить namespace
материал ... вы всегда можете использовать тип typeof Cmd.StopServer
вместо этого.
Надеюсь, это поможет;удачи.