React+TypeScript中如何将JSON字符串键识别为数字?类型适配问题
解决TypeScript中游戏书章节键的类型匹配问题
问题场景
我是前端新手,正在把一本游戏书数字化,转成了content JSON文件,结构如下:
{"123" : {"content": "something happens","options": [[12, "Go to 12"],[13, "Go to 13"]]}}
当前章节为123时,用户阅读文本后可点击按钮跳转到章节12或13。
JS版本的组件运行正常:
function Chapters({ chapter }) { return ( <div> {content[chapter].content.split("\n").map((line, index) => ( <React.Fragment key={index}>{line}<br /><br /></React.Fragment> ))} {content[chapter].options.map((option) => ( <button>{option[1]}</button> ))} </div> ) }
但在TypeScript里遇到了类型问题:父组件通过const [chapter, setChapter] = useState(123)传入的chapter是章节号数字,但TS无法理解它是JSON对象的键(而非整个JSON对象),当前的类型定义也不符合预期:
export type Content = {[key: string | number]: {content: string,options: Option[]}} export type Option = {0: number,1: string,}
希望让TS把JSON的字符串键当作数字处理。
解决方案
1. 修正类型定义
重新定义更贴合业务逻辑的类型:
// 单个章节的结构类型 export type Chapter = { content: string; options: Option[]; }; // 选项是固定结构的元组:[目标章节号, 选项文本] export type Option = [number, string]; // Content是数字键到Chapter的映射 export type Content = Record<number, Chapter>;
Record<number, Chapter>明确了Content的键是数字类型,匹配章节号的业务含义。- 元组类型的
Option比原对象类型更准确,因为options数组的每个元素都是固定顺序的两个值。
2. 修正组件的Props类型
之前组件把chapter的类型设为Content是错误的,需明确它是章节号数字:
// 定义组件的Props类型 type ChaptersProps = { chapter: number; }; function Chapters({ chapter }: ChaptersProps) { // JSON键实际是字符串,用类型断言告诉TS content符合我们定义的Content类型 const currentChapter = (content as Content)[chapter]; return ( <div> {currentChapter.content.split("\n").map((line, index) => ( <React.Fragment key={index}> {line} <br /><br /> </React.Fragment> ))} {currentChapter.options.map((option, index) => ( <button key={index} onClick={() => setChapter(option[0])}> {option[1]} </button> ))} </div> ); }
3. 父组件状态处理
父组件的useState无需修改,TS会自动推断chapter为number类型:
const [chapter, setChapter] = useState(123);
关键说明
- JSON的键只能是字符串,但我们通过
content as Content的类型断言,让TS把这些字符串键当作数字处理——因为我们明确知道这些键都是合法的章节号数字。 - 修正后的类型定义完全贴合业务逻辑,TS能精准校验代码中的类型错误,比如误传字符串给
chapter时会直接报错。
内容的提问来源于stack exchange,提问作者Veinard
相关产品推荐
相关产品推荐

