TypeScript无法识别err为null时params必非空导致类型报错
TypeScript 无法识别元组返回值错误与有效值关联逻辑问题
问题复现代码
function makeUpdateParams(code: string | null, list: Array<{ version: number[] }>): [Error | null, number[] | null] { if (!code) return [new Error('code is empty'), null] return [null, list.flatMap(i => i.version)]; } function updateVersion(versions: number[]) { } function main() { const list = [{ version: [1, 2] }, { version: [3, 4] }]; const searchParams = new URLSearchParams(window.location.search); const [err, params] = makeUpdateParams(searchParams.get('code'), list); if (err) return console.error(err); updateVersion(params); // TSC 在此处抛出错误 }
触发报错信息
Argument of type 'number[] | null' is not assignable to parameter of type 'number[]'. Type 'null' is not assignable to type 'number[]'.(2345)
问题说明
按照业务逻辑,若makeUpdateParams返回的err为null,则params必然为有效number[]类型值,但 TypeScript 4.5.5 版本编译器无法识别二者的关联逻辑,在调用入参要求为number[]类型的updateVersion方法传入params时抛出上述类型错误,是否必须使用params as number[]类型断言、自定义类型守卫,或是params!非空断言运算符解决该问题?
解决方案
不需要强制使用断言,最符合 TypeScript 类型规范的根因解法是使用可辨识联合类型(Discriminated Unions) 明确标记返回值的互斥关系,让编译器能自动推导类型关联,比断言更安全,后续逻辑变更时编译器能自动做类型校验,不会埋下类型隐患。
原写法的返回值类型[Error | null, number[] | null]是告诉编译器两个位置的类型互相独立,理论上可以出现[null, null]、[Error, number[]]这类不符合业务逻辑的组合,TS 不会主动推导函数内部分支逻辑保证二者互斥,因此无法识别判错后的参数类型。
修改makeUpdateParams的返回值类型定义即可解决问题:
// 定义两种互斥的返回结果,明确err和params的对应关系 type SuccessResult = [err: null, params: number[]]; type ErrorResult = [err: Error, params: null]; function makeUpdateParams(code: string | null, list: Array<{ version: number[] }>): SuccessResult | ErrorResult { if (!code) return [new Error('code is empty'), null] return [null, list.flatMap(i => i.version)]; }
修改后原有判错逻辑无需改动,TS 会自动推导:当err为真值提前 return 后,剩余代码分支的params必然是number[]类型,不会再抛出类型错误。
如果不想修改函数原有返回类型,也可以根据场景选择以下方案:
- 非空断言
params!:适合逻辑100%确定的简单场景,写法最简洁,但本质是告知编译器跳过此处的非空校验,后续逻辑变更导致空值时不会有编译提示 - 显式判空校验:在调用
updateVersion前增加一层if (!params) throw new Error('unexpected invalid params')判断,不需要修改原有类型定义,也能通过类型校验,鲁棒性更强 - 自定义类型守卫:适合该类错误优先返回结构在项目中多处复用的场景,抽离统一的类型判断逻辑维护
内容的提问来源于stack exchange,提问作者Lin Du
相关产品推荐
相关产品推荐

