typescript - 使用条件类型时如何获取列表属性的类型?
问题描述
给定以下类型:
type Person = {
name: string;
};
type Family = {
parent: Person;
children: Person[];
};
我想定义另一种类型Aggregated<T>
,它会自动生成以下类型:
type FamilyAggregatedExpected = {
parent: Person[];
children: Aggregated<Person>[];
};
那是:
- 对于非列表属性,新类型包含与原始属性具有相同类型的值数组
- 对于列表属性,新类型包含一个类型为的值数组
Aggregated<T>
我对列表属性有困难。
到目前为止,我已经尝试过:
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
解决方案
有几种方法可以做到这一点;似乎最接近您的方法的一种方法是使用声明在条件类型中进行类型推断: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>[];
} */
看起来挺好的。
推荐阅读
- solr - solr中是否有父子数据结构的替代方案?
- vue.js - 为什么缩小时标签消失了
- python - 无法在 Python 中添加逗号并删除大数字的悬挂零
- reactjs - 找不到变量:initialState。我正在尝试为 REACT NATIVE 中的每个数组项映射一个数组并显示组件
- django - 如何编写用于比较 django 访问值“{{cust_package}}”和 vue.js“<%radio_price%>”的 v-if 条件
- macos - 在 Mac OS 上更改默认 Apache 版本
- vba - 从 SharePoint 打开 Outlook 模板
- node.js - M1 Big Sur 上的 Npm 安装失败 - “usr/lib/libcurl.dylib(没有这样的文件或目录)”
- java - Jar 无法从实施项目中读取属性
- python - 使用机器学习预测数字的平方根