TypeScript中<GameStateKey extends keyof GameState>语法作用是什么?
关于TypeScript泛型约束在updateEntryInGameState函数中的作用解释
你问的<GameStateKey extends keyof GameState>是TypeScript的泛型类型声明+约束,作用是实现key和对应value的类型绑定,保证类型安全,具体逻辑拆解如下:
1. 泛型部分的基础含义
<>包裹的内容是提前声明这个函数要用到的泛型类型变量,这里我们定义了一个名为GameStateKey的类型变量extends keyof GameState是对这个类型变量的约束:keyof GameState会自动提取GameState接口所有合法键名构成的联合类型,也就是"gameId" | "minPlayers" | "currentChoiceMakingPlayer" | "gameEndReason",这个约束表示GameStateKey的取值只能是上述四个字符串字面量的其中之一。
2. 泛型如何应用到函数参数
声明完泛型变量后,就可以在后续的参数、返回值类型定义中复用这个变量:
- 第一个参数
key的类型定义为GameStateKey:保证你传入的键名一定是GameState接口中存在的属性,如果你打错字、传入不存在的键名,TypeScript会在编译阶段直接报错,提前规避错误。 - 第二个参数
value的类型定义为GameState[GameStateKey]:这是TypeScript的索引访问类型,意思是value的类型必须和你传入的key对应的GameState属性类型完全匹配。比如你传入的key是"minPlayers",TypeScript会自动推导GameStateKey的实际类型是"minPlayers",对应的value类型就会被限定为number;如果传入的key是"gameId",value就会被限定为string,实现了key和value的类型绑定。
3. 为什么不直接写固定类型?
如果不用泛型,直接把函数定义成如下形式:
updateEntryInGameState = (key: keyof GameState, value: GameState[keyof GameState]) => { this.gameState[key] = value; };
TypeScript只会校验key是四个合法键之一、value是四个属性类型(string|number|undefined)之一,无法把key和value的类型绑定。比如你传入key为minPlayers,value传一个字符串,TypeScript也不会报错,存在类型安全隐患。而用泛型的写法就完全规避了这个问题。
注意:上述泛型逻辑仅在TypeScript编译阶段生效,编译后的JavaScript代码中不会保留相关逻辑,它的作用就是在开发阶段帮你做类型校验,减少低级错误。
内容的提问来源于stack exchange,提问作者Hokkyokusei
相关产品推荐
相关产品推荐

