如何让TypeScript基于外部函数实现类型收窄?
实现全局变量X/Y的类型收窄方案
你需要的功能是可行的,但原代码里TypeScript无法自动推断回调执行时X/Y的非null状态——因为回调的类型检查独立于checkNull的条件判断逻辑。以下是两种可行的解决方式:
方案一:使用类型守卫关联全局变量类型
先定义一个类型守卫函数,明确判断X和Y同时非null的状态,让TypeScript能在checkNull内部识别到类型收窄:
type Bar = {}; // 示例Bar类型 const X: string | null = "demo"; const Y: Record<string, Bar> | null = { demo: {} }; // 类型守卫:断言X和Y同时为非null类型 const bothNotNull = (): X is string => X !== null && Y !== null; const checkNull = <T>(cb: () => T): T | null => { if (!bothNotNull()) return null; // 此时TypeScript已知X/Y非null,回调内不会再提示null风险 return cb(); }; const getBar = () => checkNull(() => Y[X]); // 无类型错误
方案二:将非null变量传入回调
直接在checkNull内部完成X/Y的非null断言,并将其作为参数传递给回调,从根源上避免回调内的类型歧义:
type Bar = {}; const X: string | null = "demo"; const Y: Record<string, Bar> | null = { demo: {} }; const checkNull = <T>(cb: (x: string, y: Record<string, Bar>) => T): T | null => { if (X === null || Y === null) return null; // 执行回调时传入已收窄类型的X/Y return cb(X, Y); }; // 回调直接使用非null的参数 const getBar = () => checkNull((x, y) => y[x]); // 无类型错误
核心原因
原代码中,回调函数的类型检查是独立进行的,TypeScript无法感知到checkNull内部的条件判断对全局变量X/Y的类型影响。通过类型守卫明确状态,或是将收窄后的变量直接传递给回调,就能让TypeScript正确识别回调执行时的类型约束。
内容的提问来源于stack exchange,提问作者branperr
相关产品推荐
相关产品推荐

