【问题标题】:How to capture type argument of nested property and map it to something else如何捕获嵌套属性的类型参数并将其映射到其他内容
【发布时间】:2018-04-09 20:00:20
【问题描述】:

我真的不知道如何问这个问题,所以我认为最好的方法是举一个我正在尝试做的事情的例子。假设我有以下对象:

const obj = {
  one: 'some string',
  two: new Set<string>(),
};

现在我想编写一个函数来接收该对象并将Sets 转换为相同类型的Arrays。

这是无类型的 javascript 实现:

const obj = {
  one: 'some string',
  two: new Set().add('one').add('two'),
};

function convertToArrays(objWithSets) {
  return Object.entries(objWithSets).reduce((objectWithArrays, [key, value]) => {
    if (value instanceof Set) {
      objectWithArrays[key] = Array.from(value);
    } else {
      objectWithArrays[key] = value;
    }
    return objectWithArrays;
  }, {});
}


console.log('converted', convertToArrays(obj));

我怎样才能正确输入上述函数?澄清一下:它可以接收任何对象(不仅仅是一个、两个示例),如果它看到 Set&lt;T&gt;,它会将其转换为一个Array&lt;T&gt;

我知道它需要捕获内部Set 的类型(在本例中为string)并有条件地将该类型映射到Array&lt;string&gt;

谢谢!

【问题讨论】:

  • 啊,你的意思是如果对象中的任何键引用了一个集合,请将其转换为一个数组。
  • @y2bd 是的,我很抱歉????

标签: typescript typescript2.8 conditional-types


【解决方案1】:

您可以混合使用映射类型和条件类型来执行此操作:

type InnerSetToArray<T> = { 
    [P in keyof T]: 
        T[P] extends Set<infer U> 
            ? Array<U> 
            : T[P] 
};

type InnerSet = { one: number, two: Set<string>, three: Set<Function>, four: Date };

// InnerArray === { one: number, two: string[], three: Function[], four: Date }
type InnerArray = InnerSetToArray<InnerSet>;

编辑:下面是原始的,过于具体的答案:

我们开始吧,基本上就像你描述的那样:

function convertToArrays<T extends { one: string, two: Set<any> }>(objWithSets: T):
    T extends { one: string, two: Set<infer U> }
        ? { one: string, two: Array<U> }
        : never {
  /* ... */
}

// typeof x === { one: string, two: number[] }
const x = convertToArrays({ one: "hello", two: new Set([1, 2, 3]) })

我们允许它最初是 Set&lt;any&gt; 只是为了充当类型保护,然后用条件推断实际类型。如果匹配失败,条件会缩小到never,这应该没问题,因为理论上初始检查可以保证条件始终评估为真。

【讨论】:

  • 哎呀,意识到 TS2.7 示例实际上不起作用;这里需要条件类型。
  • 你确实回答了我的问题,但我实际上是想问另一个 ?。我的意思是{one: string; two: Set&lt;T&gt;} 暗示任何对象,如果遇到Set&lt;T&gt; 将其转换为Array&lt;T&gt;。我会补充说明
  • 我已经扩展了我的答案以处理一般情况。
猜你喜欢
  • 2019-03-12
  • 2012-02-15
  • 2021-08-05
  • 1970-01-01
  • 1970-01-01
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多