You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让TypeScript识别参数为null时会抛出错误?

TypeScript 重构辅助函数后类型缩小失效的解决方法

问题场景

原本的代码中,直接在函数内做非空判断并抛错,TypeScript 可以正确识别后续代码中arg.value是已定义的:

const handleParse = (arg: { value: boolean } | null) => {
    if (!arg?.value) {
        throw new Error(`\`arg\` is null`)
    }
    
    return arg.value;
}

但将抛错逻辑抽成辅助函数后,TypeScript 无法识别arg已被校验过,提示'arg' is possibly null:

const checkDependency = (dependency: any) => {
    if (!dependency) {
        throw new Error(`\`dependency\` is null`)
    }
}

const handleParse = (arg: { value: boolean } | null) => {
    checkDependency(arg)
    
    return arg.value;
//         ^^^ 'arg' is possible null
}

调整辅助函数的返回类型为Error | void也无法解决问题:

const checkDependency = (dependency: any): Error | void => {
    if (!dependency) {
        throw new Error(`\`arg\` is null`)
    }

    return;
}

解决方法

核心是让 TypeScript 知道:辅助函数执行完成后,传入的参数一定是非空的。可以通过以下两种方式实现:

方式一:使用断言函数(Assertion Functions)

TypeScript 3.7 及以上支持断言函数,通过asserts关键字声明参数的类型约束:

// 断言函数:若函数未抛错,dependency一定是非空值
function checkDependency(dependency: unknown): asserts dependency is NonNullable<unknown> {
    if (!dependency) {
        throw new Error(`\`dependency\` is null`)
    }
}

const handleParse = (arg: { value: boolean } | null) => {
    checkDependency(arg)
    
    return arg.value; // TypeScript 现在能正确识别arg非空
}

方式二:使用类型谓词(Type Predicates)

通过返回布尔值结合类型谓词,告诉 TypeScript 参数的类型:

// 类型谓词:返回true时,dependency是非空值
function checkDependency(dependency: unknown): dependency is NonNullable<unknown> {
    if (!dependency) {
        throw new Error(`\`dependency\` is null`)
    }
    return true;
}

const handleParse = (arg: { value: boolean } | null) => {
    checkDependency(arg)
    
    return arg.value; // 类型缩小生效,无报错
}

为什么之前的方法无效

  • 使用any类型会丢失参数的原始类型信息,TypeScript 无法跟踪类型变化;
  • 声明返回类型Error | void仅描述了函数的返回值,无法关联到参数的类型约束,因此无法触发类型缩小。

内容的提问来源于stack exchange,提问作者Mike K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 12:40:31