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

能否通过泛型实现函数遇undefined时返回指定错误文本(无需try catch与默认值)

解决方案

当然可以实现,不用try/catch或默认值,结合泛型和逐段路径校验就能搞定。先说说你原代码里的几个问题:

  • 泛型参数和全局returnType类型重名,容易混淆报错
  • 用forEach遍历路径没法中途中断,而且一旦中间值变成undefined,后续访问属性会直接报错
  • 完全没处理值为undefined的场景,直接用类型断言会导致类型不安全

下面是优化后的实现:

// 泛型T表示错误文本的类型,返回值为路径对应的属性类型 | T
function getValue<T>(path: string, obj: Record<string, unknown>, errorText: T): unknown | T {
  let currentValue: unknown = obj;
  const pathSegments = path.split('.');

  for (const segment of pathSegments) {
    // 每一步都检查当前值是否是可索引的对象/数组,并且包含当前路径段
    if (typeof currentValue === 'object' && currentValue !== null && segment in (currentValue as Record<string, unknown>)) {
      currentValue = (currentValue as Record<string, unknown>)[segment];
    } else {
      // 路径不存在,直接返回错误文本
      return errorText;
    }
  }

  // 遍历完路径后,检查最终值是否为undefined,是就返回错误文本
  return currentValue === undefined ? errorText : currentValue;
}

// 测试示例
const stroka: string = 'a.b.c'; 
const alerts: string = 'asd';
console.log(getValue(stroka, {a: {b:{f: 3}}}, alerts)); // 输出: 'asd'
console.log(getValue('a.b.f', {a: {b:{f: 3}}}, alerts)); // 输出: 3

关键细节:

  • 泛型T:用来约束错误文本的类型,让函数支持返回不同类型的错误信息(比如字符串、数字都可以)
  • 逐段校验:用for...of循环代替forEach,每一步都做合法性检查,避免访问undefined的属性报错,还能中途返回错误文本
  • undefined处理:遍历结束后额外判断最终值是否为undefined,完全符合你的需求
  • 类型约束:用Record<string, unknown>代替object类型,解决了原代码里对象无法索引的问题

如果想要更精确的类型推断(让TS自动识别路径对应的属性类型),可以再加个类型工具函数:

// 递归解析路径对应的属性类型
type PathValue<T, P extends string> = 
  P extends `${infer K}.${infer Rest}` 
    ? K extends keyof T 
      ? PathValue<T[K], Rest> 
      : never 
    : P extends keyof T 
      ? T[P] 
      : never;

function getValue<O extends Record<string, unknown>, P extends string, T>(
  path: P, 
  obj: O, 
  errorText: T
): PathValue<O, P> | T {
  let currentValue: unknown = obj;
  const pathSegments = path.split('.');

  for (const segment of pathSegments) {
    if (typeof currentValue === 'object' && currentValue !== null && segment in (currentValue as Record<string, unknown>)) {
      currentValue = (currentValue as Record<string, unknown>)[segment];
    } else {
      return errorText as T;
    }
  }

  return (currentValue === undefined ? errorText : currentValue) as PathValue<O, P> | T;
}

// 测试时类型会自动推导
const testObj = {a: {b:{f: 3}}};
const result1 = getValue('a.b.f', testObj, 'asd'); // 类型为number | string
const result2 = getValue('a.b.c', testObj, 'asd'); // 类型为number | string,实际返回'asd'

这个版本能让TS自动推断出返回值的类型是路径属性类型或错误文本类型,类型安全性更高。

内容的提问来源于stack exchange,提问作者Владислав Куликов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:00:40