União discriminante do Typescript com propriedade aninhada com uma longa lista de possibilidades
Li em alguns lugares que uniões discriminantes a partir de uma propriedade aninhada não são algo viável neste momento, ou pelo menos não sem funções de guarda, e eu queria saber se há uma maneira de não usar funções de guarda de forma alguma para determinar um tipo.
O objetivo é tentar usar Enums para restringir, porque múltiplos CustomFieldType podem ter o mesmo tipo de value, e seria mais simples registrar casos a cada vez usando uma instrução switch em vez de if-elseif para restringir.
Aqui está um playground de TypeScript que tenta as diferentes possibilidades.
enum CustomFieldType {
INT = 'int',
STRING = 'string',
MULTISELECT = 'multiselect',
SELECT = 'select'
// Possibly 20 others
}
interface CustomFieldValueBase<T extends CustomFieldType> {
customField: {
type: T;
}
value: any;
}
interface CustomFieldValueInt extends CustomFieldValueBase<CustomFieldType.INT> {
value: number;
}
interface CustomFieldValueString extends CustomFieldValueBase<CustomFieldType.STRING> {
value: string;
}
interface CustomFieldValueMultiSelect extends CustomFieldValueBase<CustomFieldType.MULTISELECT> {
value: number[];
}
interface CustomFieldValueSelect extends CustomFieldValueBase<CustomFieldType.SELECT> {
value: number[];
}
type CustomFieldValue =
| CustomFieldValueInt
| CustomFieldValueString
| CustomFieldValueMultiSelect
| CustomFieldValueSelect
// Solution wanted
// Won't narrow
function guessType(cfv: CustomFieldValue) {
switch (cfv.customField.type) {
case CustomFieldType.INT:
return cfv.value // should be narrowed to number
case CustomFieldType.STRING:
return cfv.value // should be narrowed to string
case CustomFieldType.MULTISELECT:
case CustomFieldType.SELECT:
return cfv.value // should be narrowed to number[]
default: throw new Error()
}
}