TypeScript未强制校验void返回类型的原因及强制校验方案咨询
行为原因
TypeScript 中 void 作为函数返回类型的设计语义是 调用方不需要关注函数的返回值,而非「函数不能返回任何值」,这个设计是为了兼容 JavaScript 中的大量常见写法:
- 例如数组方法
Array.prototype.forEach的回调函数类型定义为(value: T, index: number, array: T[]) => void,实际开发中我们经常会写arr.forEach(item => result.push(item))这类代码,push方法本身会返回数组的新长度,如果void强制要求不能有返回值,这类普遍存在的合法写法都会抛出错误,反而不符合开发体验。
你示例中所有 Noop 类型的函数都能通过校验就是这个原因,TypeScript 只要求调用方忽略返回值,不会限制函数本身的返回内容。而 const x: void = 1 会报错,是因为作为变量类型的 void 语义和函数返回值的 void 完全不同:变量类型的 void 代表没有任何实际值,只能被赋值为 undefined。
当你把有返回值的函数赋值给 () => void 类型的变量后,调用该变量得到的返回值类型仍为 void,即使原函数实际返回了其他值,TypeScript 也会禁止你使用这个返回值,不会产生类型安全问题。
强制校验方案
TypeScript 本身没有提供编译配置项来修改 void 返回类型的默认语义,如果你需要强制标注为 void 返回的函数不能返回任意非空值,可以采用以下两种方案:
- 使用
undefined作为返回类型替代void,就像你示例中的NoopUndef类型,TypeScript 原生就会强制校验这类函数只能返回undefined或者不写返回语句(默认返回undefined),返回其他值时会直接抛出类型错误。 - 配合 ESLint 的
@typescript-eslint插件规则做额外校验:启用@typescript-eslint/no-confusing-void-expression规则,可以检测并禁止在期望void类型的位置传入有返回值的表达式,同时也可以搭配其他自定义规则实现你需要的校验逻辑。
内容的提问来源于stack exchange,提问作者tiansivive
相关产品推荐
相关产品推荐

