Typescript如何选择和组合嵌套类型作为根类型
我有单一类型,我想将此类型重新用于连接数据:Typescript如何选择和组合嵌套类型作为根类型,typescript,typescript-typings,Typescript,Typescript Typings,我有单一类型,我想将此类型重新用于连接数据: 接口元数据{ 用户:{ id:字符串; 全名:字符串; }, 统计数据:{ 以下:数字; }, 另一个:{ 任何:任何; } } 我想按键组合一些嵌套类型 (例如:type Profile=PickAllNestedKey 我必须尝试此代码,但它只能选择单键 类型NestedPartial={ [P in keyof T[K]]:T[K][P]; }; 类型Profile=NestedPartial; 预期类型如下: 接口配置文件{ id:字符串
接口元数据{
用户:{
id:字符串;
全名:字符串;
},
统计数据:{
以下:数字;
},
另一个:{
任何:任何;
}
}
我想按键组合一些嵌套类型
(例如:type Profile=PickAllNestedKey
我必须尝试此代码,但它只能选择单键
类型NestedPartial={
[P in keyof T[K]]:T[K][P];
};
类型Profile=NestedPartial;
预期类型如下:
接口配置文件{
id:字符串;
全名:字符串;
以下:数字;
}
我将从两个不同的角度来探讨这一点
第一个问题是质疑类型的结构。为什么不显式定义嵌套类型?也许可以改进类型结构?我的意思是:
用户界面{
id:字符串;
全名:字符串;
}
接口统计信息{
以下:数字;
}
接口{
任何:任何;
}
接口元数据{
用户:用户,,
统计:统计,
另一个:另一个
}
类型Profile=用户和统计信息
定义一次以一个实体为目标的较小的原子类型可以极大地提高可读性和代码维护。然后,您可以在任何适合的地方自由使用较小的类型,而不需要从较大的类型创建它们。换句话说,这将使方法从自上而下的方法切换(创建一个大类型,然后使用拾取
,省略
等来构建较小的类型)到自下而上的方法(定义单个类型,然后将其用作更复杂类型的构建块)
也就是说,我们并不总是能够控制我们正在使用的类型。因此,在以下几个地方,您可以找到有关如何使用嵌套的Pick
s的一些指导:
我将从两个不同的角度来探讨这个问题 第一个问题是质疑类型的结构。为什么不显式定义嵌套类型?也许可以改进类型结构?我的意思是:
用户界面{
id:字符串;
全名:字符串;
}
接口统计信息{
以下:数字;
}
接口{
任何:任何;
}
接口元数据{
用户:用户,,
统计:统计,
另一个:另一个
}
类型Profile=用户和统计信息
定义一次以一个实体为目标的较小的原子类型可以极大地提高可读性和代码维护。然后,您可以在任何适合的地方自由使用较小的类型,而不需要从较大的类型创建它们。换句话说,这将使方法从自上而下的方法切换(创建一个大类型,然后使用拾取
,省略
等来构建较小的类型)到自下而上的方法(定义单个类型,然后将其用作更复杂类型的构建块)
也就是说,我们并不总是能够控制我们正在使用的类型。因此,在以下几个地方,您可以找到有关如何使用嵌套的Pick
s的一些指导:
根据您的示例,所需的行为似乎是选择
元数据的顶级属性,然后“展平”结果
当前尝试的问题是T[K]
的键。如果K
是一个类似于'user'|'stats'
的联合,那么T[K]
是两个对象的联合{id:string;fullName:string;}{following:number;}
该联合体上没有共享密钥。因此,在T[K]
中没有可分配给P的P
如果我们只是选择我们想要的属性,并通过键对它们进行索引,那么我们几乎可以得到我们想要的类型,除了它是一个并集,我们需要一个交集。Pick[K]
解析为:
{
id: string;
fullName: string;
} | {
following: number;
}
type Profile = {
id: string;
fullName: string;
} & {
following: number;
}
我们可以利用效用类型来解决这个问题
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
type NestedPartial<T, K extends keyof T> = UnionToIntersection<Pick<T, K>[K]>;
type Profile = NestedPartial<MetaData, 'user' | 'stats'>;
根据您的示例,所需的行为似乎是选择元数据的顶级属性,然后“展平”结果
当前尝试的问题是T[K]
的键。如果K
是一个类似于'user'|'stats'
的联合,那么T[K]
是两个对象的联合{id:string;fullName:string;}{following:number;}
该联合体上没有共享密钥。因此,在T[K]
中没有可分配给P的P
如果我们只是选择我们想要的属性,并通过键对它们进行索引,那么我们几乎可以得到我们想要的类型,除了它是一个并集,我们需要一个交集。Pick[K]
解析为:
{
id: string;
fullName: string;
} | {
following: number;
}
type Profile = {
id: string;
fullName: string;
} & {
following: number;
}
我们可以利用效用类型来解决这个问题
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
type NestedPartial<T, K extends keyof T> = UnionToIntersection<Pick<T, K>[K]>;
type Profile = NestedPartial<MetaData, 'user' | 'stats'>;
谢谢你的回答。它是有效的。但是这个类型是在另一个库中定义的。那么我应该怎么做呢?谢谢你的回答。它是有效的。但是这个类型是在另一个库中定义的。那么我应该怎么做呢?