Я создал игру под названием риск с использованием машинописи и реакции на хуки. Игра ведется на какой-то карте. Итак, в первую очередь у меня есть дизайн I MapEditor
. Состояние редактора карт выглядит как
export interface IMapEditorState {
mousePos: IPoint;
countries: {[k: string]: ICountry};
continents: { [k: string]: IContinent };
}
countries
и continents
объекты. Интерфейс для страны выглядит так:
//The "name" property and above key will be same in `{[k: string]: ICountry};` will be same
export interface ICountry {
name: string;
border: IDot[];
neighbours: string[];
completed: boolean;
}
Теперь я делаю функцию редуктора. Для всех типов действий я использовал два реквизита name
и data
. name
всегда будет string
, а тип данных будет зависеть от name
type ActionTypes = {name: "removeCountry", data: string} | {name: "addCountry", data: ICountry};
const reducer = (state: IMapEditorState, action: ActionTypes) => {
...
}
Теперь рассмотрим первый тип в ActionTypes
, который {name: "removeCountry", data: string}
. В методе отправки я буду использовать {name: "removeCountry"}
, компилятор заставит передать data
как string
, но это не может быть любая строка, которую я не хочу. Я хочу, чтобы я мог передавать только строку, которая является ключом {[k: string]: ICountry}
в IMapEditorState
или name
в ICountry
.
Есть ли способ, которым я мог бы создать подтип строки с именем CountryName
и ее использование
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};
Я буду очень благодарен, если вы мне поможете и любезно предоставите свой взгляд на мою структуру данных, если у вас есть представление о том, что такое игра.