Typescript diskriminant union med nästlad egenskap med en lång lista av möjligheter
Jag läste på några ställen att diskriminanta unioner från en nästlad egenskap inte är något genomförbart just nu, eller åtminstone inte utan skyddsfunktioner och jag ville veta om det finns ett sätt att inte använda skyddsfunktioner alls för att bestämma en typ.
Målet är att försöka använda Enums för att begränsa eftersom flera CustomFieldType kan ha samma typ av value, och det skulle vara enklare att registrera fallen varje gång genom att använda ett switch-uttalande snarare än if-elseif för att begränsa.
Här är en TypeScript-lekplats som försöker de olika möjligheterna.
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()
}
}