首页 > 解决方案 > 使用条件类型时如何获取列表属性的类型?

问题描述

给定以下类型:

type Person = {
  name: string;
};

type Family = {
  parent: Person;
  children: Person[];
};

我想定义另一种类型Aggregated<T>,它会自动生成以下类型:

type FamilyAggregatedExpected = {
  parent: Person[];
  children: Aggregated<Person>[];
};

那是:

我对列表属性有困难。

到目前为止,我已经尝试过:

export type Aggregated<T> = {
  [key in keyof T]: T[key] extends any[] ? Aggregated<any>[] : T[key][];
};

但这不键入Aggregated类型参数。试图解决这个问题:

export type Aggregated<T,U = never> = {
  [key in keyof T]: T[key] extends U[] ? Aggregated<U>[] : T[key][];
}; 

这并不像extends U[]往常一样失败。

如何提取列表元素类型以便将其传递给Aggregated<T>

Stackblitz:https ://stackblitz.com/edit/so-conditional-types?file=index.ts

标签: typescripttypes

解决方案


有几种方法可以做到这一点;似乎最接近您的方法的一种方法是使用声明在条件类型中进行类型推断:infer

type Aggregated<T> = {
  [K in keyof T]: T[K] extends Array<infer U> ? Aggregated<U>[] : T[K][];
};

K对于 的键中的每个属性键T,我们检查是否T[K]是一个类型的数组Array<infer U>。如果是这样,U将是数组的元素类型,我们可以Aggregated根据需要将其传递给。让我们确保它有效:

type FamilyAggregated = Aggregated<Family>
/* type FamilyAggregated = {
    parent: Person[];
    children: Aggregated<Person>[];
} */

看起来挺好的。

Playground 代码链接


推荐阅读