如何让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
相关产品推荐
相关产品推荐

