I am converting some old project to Typescript recently and got stuck with some nested object types… Basically I have two types created based on backend response object and they have some common properties eg. index
but also some unique ones eg. sharkEnabled
:
type TSharkItem = {
index: string;
sharkEnabled: boolean;
};
type TGrapeItem = {
index: string;
grapeEnabled: boolean;
};
// Union type of data for later use
type TData = TGrapeItem[] | TSharkItem[];
Now I have mapping function mapDataToState
which will need to know which type of TData
to use and create proper state out of it. To do that, there was created some kind of “connector/mapping” between fields:
// Connector/mapping
const columnMap = {
fruit: {
enabledColumn: "grapeEnabled",
},
fish: {
enabledColumn: "sharkEnabled",
},
} as const;
type ColumnMap = typeof columnMap;
type AvailableColumnName = ColumnMap["fish"] | ColumnMap["fruit"];
// Return type of mapDataToState fn
type State = { isEnabled: boolean }[];
const mapDataToState = (data: TData, columnNames: AvailableColumnName): State => {
return data.reduce((memo, row) => {
return [
...memo,
{
isEnabled: row[columnNames.enabledColumn], // ERROR: Property 'grapeEnabled' does not exist on type 'TSharkItem | TGrapeItem'.
},
];
}, [] as State);
};
I understood the error from TS, that for sure grapeEnabled
only exist in TGrapeItem
type, not TSharkItem
– but unfortunately I’m quite fresh in TS world and I’m not sure if that’s even possible to achieve.
Any hints much appreciated 🙂
Link to TS playground: