能否让JSLint将toBeDefined识别为TypeScript测试中的空值检查?
解决TS18047:让TypeScript识别Jest断言的类型守卫作用
首先明确:TypeScript默认不会把Jest的toBeDefined()/.not.toBeNull()这类断言当成类型收缩的依据,所以即便你先断言了变量非空,后续访问属性还是会触发TS18047警告。
你不需要用可选链或者额外的if判断来冗余代码,只需要给Jest的断言函数添加类型守卫声明,让TypeScript知道这些调用能缩小变量类型。
具体做法:
在你的项目中创建一个jest.d.ts(或任何.d.ts类型声明文件,确保它被TypeScript配置识别),添加以下内容:
declare namespace jest { interface Expectation<T> { // 标记toBeDefined为类型守卫,断言值非null/undefined toBeDefined(): asserts this is Expectation<NonNullable<T>>; not: { toBeNull(): asserts this is Expectation<Exclude<T, null>>; toBeUndefined(): asserts this is Expectation<Exclude<T, undefined>>; }; } }
添加完这个声明后,TypeScript就会理解expect(myVar).toBeDefined()实际上是在做类型断言——确认myVar不可能是null或undefined,后续访问myVar.id、myVar.title就不会再触发TS18047警告了。
为什么你的两个方案冗余?
- 方案1的
?.可选链完全没必要,因为你已经通过toBeDefined()确认了变量存在,可选链在这里属于多余的空值处理。 - 方案2的if块虽然能让TypeScript收缩类型,但手动加判断会让测试代码变得臃肿,不如通过类型声明一次性解决所有同类问题。
另外补充:你提到的JSLint其实和这个问题无关——JSLint是代码风格检查工具,而TS18047是TypeScript的类型检查错误,真正起作用的是TypeScript的类型系统,我们上面的方案就是通过扩展类型声明让TypeScript识别Jest断言的作用。
内容的提问来源于stack exchange,提问作者velis
相关产品推荐
相关产品推荐

