如何在TypeScript中安全调用以字符串参数传入的函数?
解决方案
要解决这个类型安全问题,我们可以通过泛型约束方法名+自动推导返回类型实现,不需要枚举,还能在编译阶段拦截非法输入:
步骤1:约束方法名的泛型类型
把函数的泛型参数K约束为IExample的键,且仅保留对应属性为函数的键(过滤非方法属性)。再用ReturnType工具类型自动推导方法的返回值类型,不用手动指定泛型T。
步骤2:修正类型匹配逻辑
原代码里直接赋值ex[f]给T存在类型不匹配(ex[f]是方法本身,而你期望返回方法执行结果),所以需要调用方法后返回结果。
修改后的完整代码:
interface IExample{ getNumber(): number; getString(): string; // 新增示例方法 } class Example implements IExample { getNumber(): number{ return 10; } getString(): string { return "TypeScript类型安全"; } } // 泛型K约束为IExample中仅包含函数的键 function handleClassInteraction<K extends keyof Pick<IExample, { [P in keyof IExample]: IExample[P] extends Function ? P : never }[keyof IExample]>>(f: K): ReturnType<IExample[K]> { // 你的其他业务逻辑 const ex = new Example(); // 调用方法并返回结果,类型自动匹配 return ex[f](); } // 调用示例:无需手动指定泛型,TypeScript自动推导返回类型 const num = handleClassInteraction("getNumber"); // num类型为number const str = handleClassInteraction("getString"); // str类型为string // 编译报错:"getInvalid"不是IExample的方法名 // const err = handleClassInteraction("getInvalid");
关键说明
- 泛型约束:
K extends keyof Pick<...>确保传入的f只能是IExample中存在的方法名,修改方法名时如果调用处没同步更新,会直接触发编译错误,避免运行时崩溃。 - 自动类型推导:
ReturnType<IExample[K]>根据传入的方法名自动获取对应返回值类型,无需手动传递<number>或<string>,减少冗余代码。 - 非函数属性过滤:如果
IExample里有非函数属性(比如id: number),Pick逻辑会自动排除这些属性,确保传入的只能是可调用的方法名。
如果你的需求是返回方法本身而非执行结果,只需修改返回类型并去掉方法调用:
function handleClassInteraction<K extends keyof Pick<IExample, { [P in keyof IExample]: IExample[P] extends Function ? P : never }[keyof IExample]>>(f: K): IExample[K] { const ex = new Example(); return ex[f]; } // 调用后得到方法本身,类型为()=>number const getNumFn = handleClassInteraction("getNumber"); const num = getNumFn(); // num类型为number
内容的提问来源于stack exchange,提问作者Scorpia
相关产品推荐
相关产品推荐

