TypeScript如何编写支持静态值/函数的泛型解包函数
问题原因
TS 编译器无法区分 typeof value === "function" 命中的是联合类型里的 () => T,还是本身就是函数类型的 T,因此会报错提示返回值类型不匹配。
解决方案
方案1:约束泛型排除函数类型(推荐)
如果你的业务场景中 T 永远不会是函数类型,直接给泛型添加上非函数约束即可从类型层面彻底解决问题:
type StaticOrDynamic<T> = T | (() => T); // 给T添加约束,排除函数类型 function unwrap<T extends Exclude<unknown, Function>>(value: StaticOrDynamic<T>): T { if (typeof value === "function") { return value(); } return value; }
该方案完全兼容你现有使用方式,示例调用如下:
const x: StaticOrDynamic<string> = "foo"; console.log(unwrap(x)); // 输出 foo const y: StaticOrDynamic<string> = () => "bar"; console.log(unwrap(y)); // 输出 bar
注:你给出的示例代码中第二个打印语句误写了变量名,应该调用
y而非x。
方案2:使用类型断言兼容T为函数的场景
如果你确实需要支持T为函数类型的特殊场景,可以通过类型断言告诉编译器此处的函数就是用于生成T的工厂函数:
function unwrap<T>(value: StaticOrDynamic<T>): T { if (typeof value === "function") { // 断言value为工厂函数类型 return (value as () => T)(); } return value; }
注意:该场景下如果
T本身是函数类型,逻辑上无法区分传入的是静态函数值还是生成函数的工厂函数,需要你自己保证业务逻辑的正确性。
内容的提问来源于stack exchange,提问作者Marco Bolis
相关产品推荐
相关产品推荐

