如何让TypeScript识别条件抛出的异常,消除返回值类型错误?
解决TypeScript抽离异常处理后的类型错误问题
原代码运行正常,无类型问题:
const loadSomething = () => { try { return { foo: 'bar' } } catch (e) { console.error(e) throw e } } const main = () => { const result = loadSomething() console.log(result.foo) }
抽离异常处理逻辑后,TypeScript提示result可能为undefined,但实际catch块已重新抛出异常,不会执行到return undefined:
const logError = (e: any, rethrow: boolean) => { console.error(e) if (rethrow) { throw e } } const loadSomething = () => { try { return { foo: 'bar' } } catch (e) { logError(e, true) } return undefined } const main = () => { const result = loadSomething() console.log(result.foo) // TypeScript提示:result可能为undefined }
解决方法
给logError添加函数重载签名,让TypeScript明确:当rethrow为true时,函数会抛出异常、不会正常返回:
// 重载1:rethrow为true时,函数返回never(表示不会正常返回) function logError(e: any, rethrow: true): never; // 重载2:rethrow为false时,函数返回void function logError(e: any, rethrow: false): void; // 函数实现 function logError(e: any, rethrow: boolean) { console.error(e); if (rethrow) { throw e; } } const loadSomething = () => { try { return { foo: 'bar' } } catch (e) { logError(e, true) } // TypeScript会推断这行代码永远不会执行,不会将undefined纳入返回类型 return undefined } const main = () => { const result = loadSomething() console.log(result.foo) // 不再有类型错误 }
原理
never是TypeScript的特殊类型,代表函数永远不会正常返回(要么抛出异常,要么进入无限循环)。通过重载签名告知TypeScript:传入rethrow: true时,logError会抛出异常,后续代码不会执行。因此loadSomething的返回类型会被正确推断为{ foo: string },而非{ foo: string } | undefined,从而消除类型错误。
内容的提问来源于stack exchange,提问作者CommanderData
相关产品推荐
相关产品推荐

