gpt4 book ai didi

javascript - 如何在 typescript 中制作字符串的子类型

转载 作者:行者123 更新时间:2023-12-04 02:39:46 24 4
gpt4 key购买 nike

我使用 typescript 和 react hooks 制作了一个名为 risk 的游戏。游戏在某种 map 上进行。所以首先我设计了 MapEditor。 map 编辑器的状态是这样的

export interface IMapEditorState {
mousePos: IPoint;
countries: {[k: string]: ICountry};
continents: { [k: string]: IContinent };
}

countriescontinents 是对象。国家的界面看起来像

//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;
}

现在我做一个reducer函数。对于所有类型的操作,我使用了两个 Prop namedataname 将始终是一个 string,data 将是一个类型,具体取决于 name

type ActionTypes = {name: "removeCountry", data: string} | {name: "addCountry", data: ICountry};
const reducer = (state: IMapEditorState, action: ActionTypes) => {
...
}

现在看到 ActionTypes 中的第一个类型是 {name: "removeCountry", data: string}。在调度方法 a 中,我将使用 {name: "removeCountry"} 编译器将强制将 data 作为 string 传递,但 不能是任何我不想要的字符串。我希望我只能在 IMapEditorStatename 中传递作为 {[k: string]: ICountry} 键的字符串在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};

如果你能帮助我,我将非常感激,如果你知道游戏是什么,请提出你对我的数据结构的看法。

最佳答案

如果您希望能够在编译时进行这些检查,则必须列出所有可能的国家/地区名称:

type CountryName = 'cName1' | 'cName2' | 'cName3';

或者,如果你可以定义一个所有可能国家的初始对象,你可以将它声明为const(这样TS就不会泛化它的字符串),然后通过获取它的键>keyof:

const initialCountries = {
cName1: {
name: 'cName1',
completed: false
// ...
},
cName2: {
name: 'cName2',
completed: false
},
cName3: {
name: 'cName3',
completed: false
},
} as const;
type CountryName = keyof typeof initialCountries;

CountryName 的结果是 "cName1"| “cName2” | “cName3”

然后你可以使用上面的CountryName定义IMapEditorState:

export interface ICountry {
name: CountryName;
border: IDot[];
neighbours: string[];
completed: boolean;
}
export interface IMapEditorState {
mousePos: IPoint;
countries: { [k: CountryName]: ICountry };
continents: { [k: string]: IContinent };
}

然后将编译以下内容:

const initalIMapEditorState: IMapEditorState = {
countries: initialCountries,
// ...
};

然后您可以在任何需要的地方使用 CountryName:

type ActionTypes = {name: "removeCountry", data: CountryName} | {name: "addCountry", data: ICountry};

关于javascript - 如何在 typescript 中制作字符串的子类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59907282/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com