I am currently working on developing a game called Risk using TypeScript and React hooks. This game is played on a map, so my first step was to design a MapEditor
. The state of the Map Editor is as follows:
export interface IMapEditorState {
mousePos: IPoint;
countries: {[k: string]: ICountry};
continents: { [k: string]: IContinent };
}
The objects countries
and continents
are essential components. Here is the interface for the country object:
//The "name" property in each key will be the same in `{[k: string]: ICountry}`;
export interface ICountry {
name: string;
border: IDot[];
neighbours: string[];
completed: boolean;
}
Next, I created a reducer function. For all types of actions, I utilized two props: name
and data
. The name
prop will always be a string
, while the data type will vary based on the name
:
type ActionTypes = {name: "removeCountry", data: string} | {name: "addCountry", data: ICountry};
const reducer = (state: IMapEditorState, action: ActionTypes) => {
...
}
In the ActionTypes
, the first type is
{name: "removeCountry", data: string}
. When using {name: "removeCountry"}
in the dispatch method, the compiler enforces that the data
passed must be a string
. However, this string should be specific to the keys in {[k: string]: ICountry}
within the IMapEditorState
or the name
attribute in ICountry
.
I explored creating a subtype of a string named CountryName
, which could be used like this:
export interface IMapEditorState {
mousePos: IPoint;
countries: {[k: CountryName]: ICountry};
continents: { [k: string]: IContinent };
}
export interface ICountry {
name: CountryName;
border: IDot[];
neighbours: string[];
completed: boolean;
}
type ActionTypes = {name: "removeCountry", data: CountryName} | {name: "addCountry", data: ICountry};
Any insights you have on my data structure for the game would be greatly appreciated!