首页 > 解决方案 > 使用条件映射键时正确解析对象项类型(键应用于对象)

问题描述

希望我只是错过了一些东西,有人可以指出它,但是我遇到了一个问题,当 TS 无法正确确定由属性获取的对象项值的类型时,该属性的名称是从该项有条件地映射的类型。

假设我们有一个接口,它的一些属性包含一个特定类型的数组。

interface Aa {
  foo: string;
  bar: Bb[];
}

interface Bb {
  zap: string;
}

在此基础上,创建一个新接口,在我们的例子中,它将限制“prop”属性仅等于“bar”,其中存储了 B[]。想象一下,还会有其他类似的类型组合。

interface Kk<T, U> {
  prop: {[keyT in keyof T]: T[keyT] extends U[] ? keyT : never}[keyof T];
}

const key: Kk<Aa, Bb> = {
  prop: 'bar'
};

它按预期工作:“key”不能具有“bar”以外的“prop”值。

但是,当涉及到通过该属性引用值时,就会出现 TS 问题,该项目没有 forEach 方法。

let b1: Bb = { zap: 'b1' }, b2: Bb = { zap: 'b2' };
let a1: Aa = { foo: 'foo', bar: [b1, b2] };

function f<T, U>(k: K<T, U>, a: T) {
    a[k.prop].forEach((b: Bb) => { console.log(b); }); // TS no forEach 
    return k.prop;   
}

正如here相关帖子中所描述的那样,问题似乎是 T 出现在函数签名中“太频繁”。如果我们尝试使用函数的结果作为键,则不会出错。

let k = f(key, a1);
a1[k].forEach(() => {});

我仍然希望有一个干净的解决方案,我错过了一些东西。

链接到TS 游乐场

标签: typescripttypescript-typingsconditional-types

解决方案


推荐阅读