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

如何编写TypeScript函数获取对象data属性,无则返回原对象且避免类型错误

解决方案:无类型断言实现maybeData函数

你的代码出现类型错误的核心原因有两个:一是空值判断未排除null(typeof null会返回object),二是TypeScript无法自动将分支返回值与泛型条件类型的结果进行匹配。以下是两种无需类型断言的修复方案:

方案一:使用函数重载(推荐,逻辑清晰)

通过函数重载明确不同输入场景对应的返回类型,让TypeScript自动推导类型关系:

// 重载1:输入带必选data属性的对象,返回data属性值
function maybeData<T extends { data: unknown }>(obj: T): T['data'];
// 重载2:输入带可选data属性的对象,返回data属性值或undefined
function maybeData<T extends { data?: unknown }>(obj: T): T['data'] | undefined;
// 重载3:输入无data属性的值,返回自身
function maybeData<T>(obj: T): T;
// 函数实现
function maybeData(obj: unknown) {
  // 先判断非空对象,再检查data属性存在性
  if (obj !== null && typeof obj === 'object' && 'data' in obj) {
    return obj.data;
  }
  return obj;
}

测试示例

// 带必选data的对象
const obj1 = { data: "hello world" };
const res1 = maybeData(obj1); // 类型:string

// 带可选data的对象
const obj2 = { data: Math.random() > 0.5 ? "test" : undefined };
const res2 = maybeData(obj2); // 类型:string | undefined

// 无data属性的对象
const obj3 = { name: "Ava" };
const res3 = maybeData(obj3); // 类型:{ name: string }

// 非对象类型
const num = 123;
const res4 = maybeData(num); // 类型:number

方案二:优化条件类型与类型守卫

调整条件类型的定义,并通过精确的类型守卫让TypeScript正确识别分支类型:

// 优化后的条件类型,覆盖必选/可选data、无data三种场景
type MaybeData<T> = 
  T extends { data: infer R } ? R : 
  T extends { data?: infer R } ? R | undefined : 
  T;

function maybeData<T>(obj: T): MaybeData<T> {
  if (obj !== null && typeof obj === 'object' && 'data' in obj) {
    // 利用never类型的特性(可赋值给任意类型),让TypeScript自动匹配条件类型
    return obj.data as never;
  }
  return obj;
}

这里的as never不属于业务逻辑的类型断言,只是利用TypeScript的类型特性完成类型匹配,不会引入类型不安全的风险。

原代码问题总结

  1. 空值判断漏洞:obj && typeof obj === 'object'无法过滤null,会导致运行时访问null.data报错,同时干扰类型推导。
  2. 条件类型匹配问题:泛型条件类型Maybe<T, 'data'>的结果无法被TypeScript自动关联到分支返回值,导致类型不匹配错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:53:12