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

如何从属性名数组推导对应对象类型?

这个问题我之前也碰到过,其实核心是要让TypeScript捕获到你传入的具体键集合,而不是只把它当成宽泛的数组类型。我们一步步来解决:

首先,先回顾下你的基础类型定义:

interface StoredProps { 
  location: boolean; 
  notification: boolean; 
}

type StorableKeys = keyof StoredProps;

你的原函数返回类型为{},是因为泛型T extends StorableKeys[]太宽泛了——TypeScript只会把T识别为“包含StorableKeys元素的数组”,不会记住你传入的具体键是什么。要让它推断出精确的返回类型,我们需要调整泛型约束和返回类型:

修正后的函数实现

const getStoredProps = <T extends readonly StorableKeys[]>(keys: T): { [K in T[number]]: StoredProps[K] } => {
  return keys.reduce((props, key) => {
    props[key] = storage.get(key);
    return props;
  }, {} as { [K in T[number]]: StoredProps[K] });
};

关键改动解释

  1. 泛型约束改为T extends readonly StorableKeys[]
    这样TypeScript会捕获你传入的数组的字面量类型,比如如果你传入['location', 'notification'],T就会被推断为readonly ['location', 'notification'],而不是模糊的StorableKeys[]。

  2. 返回类型使用映射类型
    { [K in T[number]]: StoredProps[K] }是核心:

    • T[number]会提取数组中所有元素的联合类型(比如'location' | 'notification')
    • 然后通过映射类型,把每个键K对应到StoredProps[K]的具体类型,最终生成和传入键完全匹配的对象类型。
  3. reduce初始值的类型断言
    初始的{}类型太宽泛,我们用as { [K in T[number]]: StoredProps[K] }告诉TypeScript:我们最终会构建出这个类型的对象,避免类型报错。

使用示例

调用时TypeScript会自动推断出精确的返回类型:

// 返回类型自动推断为 { location: boolean; notification: boolean }
const fullProps = getStoredProps(['location', 'notification']);

// 返回类型自动推断为 { notification: boolean }
const partialProps = getStoredProps(['notification']);

如果你不想用readonly约束,也可以保持泛型为T extends StorableKeys[],但调用时需要给数组加as const来让TypeScript捕获字面量类型:

const partialProps = getStoredProps(['notification'] as const);

这样就能完美实现“传入什么键,返回对应结构的类型”的需求了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:17:14