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

如何让TypeScript断言函数同时支持两种调用方式?

如何让断言函数同时支持两种调用方式

我有一个断言函数,用于确保值不为 null 或 undefined:

export function assertNonNull<T>(
  value: T,
): asserts value is NonNullable<T> {
  if (value === null || value === undefined) {
    throw new Error();
  }
}

它支持调用方式(A):调用后,类型系统会自动将原变量的类型收窄为非空类型

const foo: string | null = getFoo();
assertNonNull(foo);
const bar: string = foo; // 类型检查不报错

但我还想支持调用方式(B):直接将断言后的结果赋值给新变量

const foo: string | null = getFoo();
const bar: string = assertNonNull(foo);

如果改成返回值的形式,虽然支持(B),但会失去(A)的类型收窄能力:

export function assertNonNull<T>(
  value: T,
): NonNullable<T> {
  if (value === null || value === undefined) {
    throw new Error();
  }
  return value as NonNullable<T>;
}

请问如何编写一个函数同时支持(A)和(B)两种调用方式?


解决方案

通过TypeScript函数重载可以实现这一需求,定义两个重载签名分别对应两种调用场景:

// 重载签名1:断言模式,调用后收窄原变量类型
export function assertNonNull<T>(value: T): asserts value is NonNullable<T>;
// 重载签名2:返回值模式,直接返回非空值用于赋值
export function assertNonNull<T>(value: T): NonNullable<T>;
// 函数实现体
export function assertNonNull<T>(value: T): NonNullable<T> {
  if (value === null || value === undefined) {
    throw new Error("值不能为null或undefined");
  }
  return value as NonNullable<T>;
}

验证两种调用方式

  • 调用方式(A):类型系统会正确收窄原变量类型
const foo: string | null = getFoo();
assertNonNull(foo);
const bar: string = foo; // 类型检查通过
  • 调用方式(B):直接赋值断言后的结果
const foo: string | null = getFoo();
const bar: string = assertNonNull(foo); // 类型检查通过

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 22:13:13