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

TypeScript:能否将类型属性用作类型?实现对象与函数类型关联

TypeScript自动推断FruitPicker的泛型参数

问题背景

需要让FruitPicker对象的函数参数类型、返回值类型与其自身的availableFruits、fruitKey属性自动关联,且无需手动传递泛型参数。

初始代码尝试:

type Banana = { type: "banana" };
type Apple = { type: "apple" };
type Peach = { type: "peach" };

type Lookup = {
  banana: Banana;
  apple: Apple;
  peach: Peach;
};

type FruitPicker = {
  (deliveredFruits: /* 需关联availableFruits的类型 */) => Lookup[this.fruitKey];
  fruitKey: keyof Lookup;
  availableFruits: (keyof Lookup)[];
};

// 实现示例
const fruitPicker: FruitPicker = (deliveredFruits) => {
  return { type: "banana" };
};
fruitPicker.fruitKey = "banana";
fruitPicker.availableFruits = ["apple", "peach"];

通过泛型实现了类型关联,但必须手动指定泛型参数:

type FruitPicker<Key extends keyof Lookup, AvailableFruits extends keyof Lookup> = {
  (availableFruits: Pick<Lookup, AvailableFruits>) => Lookup[Key];
  fruitKey: Key;
  availableFruits: AvailableFruits[];
};

解决方案:使用工厂函数实现自动推断

直接声明对象时TypeScript无法自动推导泛型,但可以通过工厂函数,让TS根据传入的配置自动推断泛型参数:

type Banana = { type: "banana" };
type Apple = { type: "apple" };
type Peach = { type: "peach" };

type Lookup = {
  banana: Banana;
  apple: Apple;
  peach: Peach;
};

// 泛型工厂函数,自动推导Key和Available类型
function createFruitPicker<Key extends keyof Lookup, Available extends keyof Lookup>(
  config: { fruitKey: Key; availableFruits: Available[] },
  pickerFn: (delivered: Pick<Lookup, Available>) => Lookup[Key]
): FruitPicker<Key, Available> {
  const picker = pickerFn as FruitPicker<Key, Available>;
  picker.fruitKey = config.fruitKey;
  picker.availableFruits = config.availableFruits;
  return picker;
}

// 使用示例:无需手动传泛型,TS自动推断所有类型
const fruitPicker = createFruitPicker(
  { fruitKey: "banana", availableFruits: ["apple", "peach"] },
  (deliveredFruits) => {
    // deliveredFruits自动推断为Pick<Lookup, "apple" | "peach">
    // 返回值必须符合Banana类型
    return { type: "banana" };
  }
);

// 类型验证:
fruitPicker.fruitKey; // 类型为"banana"
fruitPicker.availableFruits; // 类型为("apple" | "peach")[]
fruitPicker({ apple: { type: "apple" }, peach: { type: "peach" } }); // 返回Banana类型

方案说明

  • 工厂函数通过接收config参数,让TypeScript自动提取fruitKey和availableFruits的类型作为泛型参数
  • 最终返回的FruitPicker实例,函数参数、返回值与对象属性的类型完全关联,无需手动指定泛型

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 15:35:22