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

如何为嵌套对象索引的取值函数编写正确TypeScript类型?

问题描述

我有一个包含固定属性的对象,其中custom属性的字段是父对象属性的子集,类型定义如下:

interface TFruit {
  weight: number;
  color: string;
  shape: 'round' | 'long' | 'oblong'
  custom: TCustom
}

interface TCustom {
  weight?: number;
  color?: string;
}

我需要实现一个函数:当custom中的属性值不为undefined时,优先取该值;否则取父对象的对应属性值。同时希望TypeScript能根据传入的属性,自动推断出返回值的精确类型。

我尝试的实现代码如下:

const getProperty = <TProperty extends keyof TCustom>(
  fruit: TFruit,
  property: TProperty
): TFruit['custom'][TProperty] extends undefined ? TFruit[TProperty] : TFruit['custom'][TProperty] => {
  const customProperty = fruit['custom'][property];

  if (customProperty !== undefined) {
    return customProperty;
  }

  return fruit[property];
}

但出现了以下类型错误:

Type 'TCustom[TProperty] & {}' is not assignable to type 'TCustom[TProperty] extends undefined ? TFruit[TProperty] : TFruit['custom'][TProperty]'.ts(2322)
解决方案

你之前的条件类型写法存在逻辑问题:TFruit['custom'][TProperty]的类型是number | undefined或string | undefined,它并不完全继承undefined,导致条件类型的结果与实际返回值类型不匹配。

正确的做法是直接将返回值类型定义为TFruit[TProperty]——因为custom的属性类型本身就是父对象对应属性的可选版本,非undefined时类型与父对象完全一致,最终返回值必然符合父对象的属性类型。同时可以用??操作符简化逻辑,让TypeScript自动识别类型:

const getProperty = <TProperty extends keyof TCustom>(
  fruit: TFruit,
  property: TProperty
): TFruit[TProperty] => {
  return fruit.custom[property] ?? fruit[property];
};

类型验证示例

const apple: TFruit = {
  weight: 100,
  color: 'red',
  shape: 'round',
  custom: { weight: 120 }
};

// 类型推断为 number
const appleWeight = getProperty(apple, 'weight');
// 类型推断为 string
const appleColor = getProperty(apple, 'color');

这样既满足了业务逻辑需求,又让TypeScript能准确推断返回值的精确类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:20:22