如何定义TypeScript函数使第二个参数类型依赖第一个参数?
问题场景
现有如下TypeScript代码结构:
const mapA = { a: 1, b: 2, c: 3, } const mapB = { a: 1, b: 2, } const maps = { A: mapA, B: mapB, } const func = (mapName: keyof typeof maps, prop: ?) => { // 需要实现逻辑 }
需求是为prop定义合适的类型,使得:
func('A', 'c')能正常返回3func('B', 'c')触发TypeScript类型错误
之前尝试的写法未成功:
const func = <T extends keyof Maps>(mapName: T, prop: Maps[T]) => { const value = maps[mapName][prop]; }
解决方案
正确的类型定义需要利用泛型约束和keyof操作符,让第二个参数的类型依赖于第一个参数的取值:
const func = <T extends keyof typeof maps>(mapName: T, prop: keyof typeof maps[T]) => { return maps[mapName][prop]; };
关键说明
- 泛型
T约束mapName只能是maps的合法键(即'A'或'B') prop的类型keyof typeof maps[T]表示:当mapName为T类型时,prop必须是对应maps[T]对象的键。比如:- 当
mapName='A'时,maps[T]是mapA,keyof typeof mapA即'a' | 'b' | 'c' - 当
mapName='B'时,maps[T]是mapB,keyof typeof mapB即'a' | 'b'
- 当
验证效果
func('A', 'c'); // 正常执行,返回3 func('B', 'c'); // TypeScript报错:类型'"c"'的参数不能赋给类型'"a" | "b"'的参数
错误原因分析
你之前的写法prop: Maps[T]存在逻辑错误:Maps[T]是对应对象的类型(比如mapA的类型是{a: number; b: number; c: number}),而非对象的键类型。需要用keyof操作符提取对象的键联合类型,才能约束prop的合法取值。
内容的提问来源于stack exchange,提问作者Chan Echo
相关产品推荐
相关产品推荐

