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

TypeScript可导出工具函数的类型守卫实现问题

正确实现TypeScript类型守卫工具函数的方案

1. 基础类型守卫(isNull、isFunction)

这类单一判断的工具函数,直接用类型谓词明确返回类型,就能让TS正确完成类型收窄:

isNull/ isUndefined

export function isNull(value: unknown): value is null {
  return value === null;
}

export function isUndefined(value: unknown): value is undefined {
  return value === undefined;
}

// 合并判断版
export function isNullOrUndefined(value: unknown): value is null | undefined {
  return isNull(value) || isUndefined(value);
}

isFunction

如果只需判断普通可调用类型,直接用typeof判断即可,类型谓词泛型可以兼容不同函数类型:

export function isFunction<T extends Function>(value: unknown): value is T {
  return typeof value === 'function';
}

2. 解决isNullOrEmpty的类型收窄问题

你遇到的never类型问题,根源是直接把目标类型定义为{} | [] | null | undefined,TS无法反向推断“非空非空”的具体类型。正确做法是从排除法入手,先明确需要保留的类型,再定义精准的类型谓词:

// 辅助类型:定义“非空非空”的合法类型
type NonNullOrEmpty<T> = T extends null | undefined 
  ? never 
  : T extends object 
    ? T extends Array<any> 
      ? T extends { length: 0 } ? never : T 
      : T extends Record<string, never> ? never : T 
    : T;

// 实现isNullOrEmpty,用Exclude反向定义类型谓词
export function isNullOrEmpty<T>(value: T): value is Exclude<T, NonNullOrEmpty<T>> {
  if (isNullOrUndefined(value)) return true;
  if (Array.isArray(value)) return value.length === 0;
  if (typeof value === 'object') return Object.keys(value).length === 0;
  // 如果需要把空字符串纳入判断,可添加:if (typeof value === 'string') return value === '';
  return false;
}

使用时,!isNullOrEmpty分支会正确推断出非空类型:

const arr: number[] | [] | null = [1,2,3];
if (!isNullOrEmpty(arr)) {
  arr.map(item => item * 2); // 类型推断为number[],无报错
}

3. isNullOrWhitespace的实现

同样用反向思维,先定义“非空白字符串”的类型,再写类型守卫:

// 辅助类型:标记非空白字符串
type NonWhitespaceString = string & { __nonWhitespace: never };

// 判断“是空/空白”的类型守卫
export function isNullOrWhitespace(value: unknown): value is null | undefined | '' | (string & { trim(): '' }) {
  if (isNullOrUndefined(value)) return true;
  if (typeof value !== 'string') return false;
  return value.trim() === '';
}

// 更直观的反向判断:直接判断“非空白字符串”
export function isNonWhitespaceString(value: unknown): value is NonWhitespaceString {
  return typeof value === 'string' && value.trim() !== '';
}

使用示例:

const str: string | null = '  hello  ';
if (isNonWhitespaceString(str)) {
  console.log(str.trim()); // str被推断为非空白字符串
}

关键技巧总结

  • 避免宽泛的“空类型”定义:优先从反向明确需要保留的类型,用Exclude或自定义类型排除无效值。
  • 类型谓词要精准:结合运行时判断逻辑,让TS能准确关联类型和代码分支。
  • 拆分复杂判断:把多条件的类型守卫拆成多个小判断(先判null/undefined,再判数组、对象),TS的类型分析会更准确。

内容的提问来源于stack exchange,提问作者C. Helling

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 15:45:32