TypeScript中如何通过传入属性名参数访问类的实例属性?
TypeScript 实现动态访问类指定属性的方案
你接触到的 keyof 关键字就是解决这类需求的核心工具,配合泛型约束就能实现和原生JS动态索引完全一致的运行时效果,同时保留TypeScript的完整类型检查能力。
基础代码准备
保持原有类的定义逻辑不变即可:
class Point { public x: number; public y: number; constructor(x: number, y: number) { this.x = x; this.y = y; } } const p = new Point(1, 2);
动态访问函数实现
通过泛型结合索引访问类型,实现既约束参数合法性,又精准推导返回值类型的效果:
function getProp<K extends keyof Point>(prop: K): Point[K] { // 运行时逻辑和JS写法完全一致,直接动态索引访问属性 return p[prop]; }
实现效果
- 传入类中存在的合法属性名时,TypeScript会自动匹配对应属性的精确类型:比如调用
getProp("x")的返回值会被推导为number,和直接访问p.x的类型完全一致 - 传入类上不存在的属性名时,TypeScript会直接抛出编译错误,提前规避拼写错误、无效属性访问的问题
关键注意点
如果不使用泛型,仅用 keyof Point 直接约束参数,会出现类型推导损失的问题:
// 不推荐的写法 function getPropBad(prop: keyof Point) { return p[prop]; }
这种写法仅能检查参数是否为类的合法属性名,但返回值会被推导为类所有属性类型的联合类型(比如类中同时存在number类型的x和string类型的label,返回值就会是number | string),无法根据传入的具体属性名匹配到对应的精确类型。
泛型 <K extends keyof Point> 的作用,就是把传入参数的具体字面量类型传递到返回值的推导环节,让类型系统能精准对应属性和返回值的关系,完全达到原生JS动态访问的效果,且没有类型安全的损耗。
内容的提问来源于stack exchange,提问作者Denis Giffeler
相关产品推荐
相关产品推荐

