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

TypeScript如何定义需包含泛型变量对应键的对象类型

结论

该需求可以在TypeScript中实现,且完全兼容noUncheckedIndexAccess: true配置,不会出现索引访问被判定为可能未定义的问题。

实现代码

基础版本(手动指定对象类型联合)

interface One {
  foo: string;
  bar: string;
}

interface Two {
  bar: string;
  foobar: string;
}

interface Three {
  foobar: string;
  foo: string;
}

// 约束传入对象必须包含T作为必填键
type SomeType<T extends PropertyKey> = {
  [K in T]: unknown;
} & Record<PropertyKey, unknown>;

/**
 * @param object 必须包含key对应字段的对象
 * @param key 字符串字面量类型的键名
 */
function fn<T extends PropertyKey, O extends SomeType<T>>(object: O, key: T) {
  // 此处访问无类型报错,TS可判定key一定是object的合法键
  const val = object[key];
  // 其余业务逻辑
}

// 调用示例
const one: One = { foo: "1", bar: "1" };
const two: Two = { bar: "2", foobar: "2" };
const three: Three = { foobar: "3", foo: "3" };

fn<"foo", One | Three>(one, "foo"); // 校验通过
fn<"foo", One | Three>(three, "foo"); // 校验通过
fn<"foo", One | Three>(two, "foo"); // 类型报错:two缺少必填键foo
fn<"bar", One | Two>(one, "bar"); // 校验通过
fn<"bar", One | Two>(two, "bar"); // 校验通过
fn<"bar", One | Two>(three, "bar"); // 类型报错:three缺少必填键bar

优化版本(自动筛选符合键要求的类型)

如果不需要手动传入对象联合类型,可以提前将所有候选接口合并为联合类型,通过条件类型自动筛选出包含指定键的类型,调用时仅需传入键名泛型即可:

// 所有待校验候选接口的联合集合
type AllCandidates = One | Two | Three;

// 从候选集合中筛选出包含K键的类型
type MatchKey<K extends PropertyKey> = AllCandidates extends infer O
  ? O extends Record<K, any>
    ? O
    : never
  : never;

function fnOpt<T extends PropertyKey>(object: MatchKey<T>, key: T) {
  const val = object[key]; // 索引访问依然安全,无noUncheckedIndexAccess报错
}

// 调用示例
fnOpt<"foo">(one, "foo"); // 校验通过,自动推导object类型为One | Three
fnOpt<"foo">(three, "foo"); // 校验通过
fnOpt<"foo">(two, "foo"); // 类型报错
fnOpt<"bar">(one, "bar"); // 校验通过,自动推导object类型为One | Two
fnOpt<"bar">(two, "bar"); // 校验通过
fnOpt<"bar">(three, "bar"); // 类型报错
实现要点
  • SomeType<T>通过映射类型强制要求传入对象必须存在T对应的键,缺键的类型会直接触发类型校验失败
  • 基础版本通过双泛型约束O extends SomeType<T>,让TypeScript能够明确判定T一定是对象O的合法键,因此开启noUncheckedIndexAccess时,object[key]不会被标记为可能为undefined
  • 优化版本通过分布式条件类型,从预定义的候选类型联合中自动过滤出包含指定键的类型,调用时不需要手动传入对象类型联合,更符合使用预期

内容的提问来源于stack exchange,提问作者Michael.Lumley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:10:33