Краткий обзор моей цели высокого уровня: у меня есть система, которая обрабатывает события на основе кодов событий, которые я не контролирую, но могу перечислять. Каждое событие может привести к различным типам действий в моей системе. Я пишу машинопись для обработки этих событий. Я хотел бы написать код, который имеет следующие свойства:
- Сильная время компиляции гарантирует, что код события обрабатывает все события для данного пути
- Единственный источник истины для информация о событиях и свойства этих событий.
Свойства моих событий, которые определяют мое поведение, выглядят примерно так:
type EventProperties = (
shouldDoX: boolean;
someOther: string;
propertiesHere: number;
};
Начиная с конечной цели того, что я хочу: я ' я хотел бы иметь возможность делать что-то вроде
function handleEvent(eventCode: EventCode) {
if (EventInfo[eventCode].shouldDoX) {
doX(eventCode);
} else {
// Type narrowed to events where shouldDoX is false
}
doSomethingCommonToAllEvents(eventCode);
}
function doX(eventCode: EventCodeThatRequiresX) {
console.log('I did X');
}
Я начал работать над определением типа, чтобы достичь этой цели, и я думаю, что в идеале оно могло бы быть организовано так:
export const EventCodes = ['CRE', 'DEL'] as const;
export type EventCode = typeof EventCodes[number];
export const EventInfo: {
[TDog in EventCode]: {
shouldDoX: boolean;
otherProp: string;
};
} = {
CRE: {
shouldDoX: true,
otherProp: 'foo'
},
DEL: {
shouldDoX: false,
otherProp: 'bar'
}
};
Это кажется лучшим подходом, так как есть принудительное выполнение во время компиляции, обеспечивающее правильную настройку события. К сожалению, я не могу понять, как писать типы для EventCodeThatRequiresX
и EventCodeThatDoesNotRequireX
, чтобы их объединения определялись содержимым объекта EventInfo. Это возможно? Кажется, что ограничение заключается в том, что следующий тип оценивается как логический, а не как ложный, что, как я полагаю, потребовало бы использования условных типов + сопоставленных типов для генерации желаемых типов.
type ShouldBeFalse = typeof EventInfo.DEL.shouldDoX;
Если это не так возможно, как бы вы предложили записать эти константы / перечисления / типы так, чтобы они сохраняли два свойства, упомянутых выше.