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

TypeScript类型定义可正常工作却报错的问题排查

TypeScript 嵌套泛型类型索引报错问题

我定义了如下只读常量对象:

const someObject = {
  topLevelKey1: {
    midLevelKeyA: {
      someProp: ['a', 'b'],
    },
  },
  topLevelKey2: {
    midLevelKeyB: {
      someProp: ['c', 'd', 'e'],
    },
    midLevelKeyC: {
      someProp: ['g'],
    },
  },
} as const;

我需要定义一个函数,签名形如someFunction(topLevelKey, midLevelKey, objectWithKeysMatchingToProp),合法调用示例为someFunction('topLevelKey2', 'midLevelKeyB', {c: 2, d: 3, e: 4})——第三个参数的键必须严格匹配对应层级下someProp数组中的元素。

为了实现第三个参数的类型约束,我写了如下泛型类型:

type X<
    T extends keyof typeof someObject,
    K extends keyof (typeof someObject)[T]
> = {
        [key in (typeof someObject)[T][K]['someProp'][number]]: number;
    };
const a: X<'topLevelKey2', 'midLevelKeyC'> = {
    f: 3 // 此处会报错,正确键应为'g'
};

奇怪的是,这个类型实际功能完全正常:能自动补全对象键、键错误时会抛出正确的类型错误,但TypeScript却在(typeof someObject)[T][K]['someProp'][number]这段代码上抛出了以下错误:

Type '"someProp"' cannot be used to index type '{ readonly topLevelKey1: { readonly midLevelKeyA: { readonly prop1: readonly []; readonly someProp: readonly ["a", "b"]; }; }; readonly topLevelKey2: { readonly midLevelKeyB: { readonly prop1: readonly []; readonly someProp: readonly ["c", "d", "e"]; }; readonly midLevelKeyC: { ...; }; }; }[T][K]'.
Type '{ readonly topLevelKey1: { readonly midLevelKeyA: { readonly prop1: readonly []; readonly someProp: readonly ["a", "b"]; }; }; readonly topLevelKey2: { readonly midLevelKeyB: { readonly prop1: readonly []; readonly someProp: readonly ["c", "d", "e"]; }; readonly midLevelKeyC: { ...; }; }; }[T][K]["someProp"][number]' is not assignable to type 'string | number | symbol'.

Type '{ readonly topLevelKey1: { readonly midLevelKeyA: { readonly prop1: readonly []; readonly someProp: readonly ["a", "b"]; }; }; readonly topLevelKey2: { readonly midLevelKeyB: { readonly prop1: readonly []; readonly someProp: readonly ["c", "d", "e"]; }; readonly midLevelKeyC: { ...; }; }; }[T][keyof { ...; }[T]]["so...' is not assignable to type 'string | number | symbol'.
Type '{ readonly topLevelKey1: { readonly midLevelKeyA: { readonly prop1: readonly []; readonly someProp: readonly ["a", "b"]; }; }; readonly topLevelKey2: { readonly midLevelKeyB: { readonly prop1: readonly []; readonly someProp: readonly ["c", "d", "e"]; }; readonly midLevelKeyC: { ...; }; }; }[T][string]["someProp"][nu...' is not assignable to type 'string | number | symbol'.
  Type '{ readonly topLevelKey1: { readonly midLevelKeyA: { readonly prop1: readonly []; readonly someProp: readonly ["a", "b"]; }; }; readonly topLevelKey2: { readonly midLevelKeyB: { readonly prop1: readonly []; readonly someProp: readonly ["c", "d", "e"]; }; readonly midLevelKeyC: { ...; }; }; }[T][string]["someProp"][nu...' is not assignable to type 'string | number | symbol'.

Type 'number' cannot be used to index type '{ readonly topLevelKey1: { readonly midLevelKeyA: { readonly prop1: readonly []; readonly someProp: readonly ["a", "b"]; }; }; readonly topLevelKey2: { readonly midLevelKeyB: { readonly prop1: readonly []; readonly someProp: readonly ["c", "d", "e"]; }; readonly midLevelKeyC: { ...; }; }; }[T][K]["someProp"]'.

添加@ts-ignore可以忽略报错并获得正常的类型安全,但这显然不是合理的解决方案。请问这个报错的原因是什么?

另外需要注意:当移除中间层的K泛型参数时,代码完全正常,不会抛出任何错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:02:13