我希望有一个类型,我知道特定的属性将被定义,但一些属性将丢失。类似这样:
type UserType = {
email: string
name: {
first: string
last: string
}
address: {
city: string
state: string
zip: string
coordinates: {
lat: number
lng: number
}
}
}
const partialUser: PickPartial<
UserType,
| 'email'
| Record<
'address',
Record<
'coordinates',
| 'lat'
| 'lng'
>
>
>
基本上我是这样选择的:
{
email: string
name?: {
first: string
last: string
}
address: {
city?: string
state?: string
zip?: string
coordinates: {
lat: number
lng: number
}
}
}
这可能吗?我看到了PartialDeep
代码,但它并不像我想的那样工作。我本质上想说的是,树中的这些特定属性是定义的(不可能是未定义的),其余的可能是未定义的?
。我如何在TypeScript中完成这一点?如果不完全正确,我可以得到什么最接近这一点,或者有什么解决方案?
另一种API方法可能是:
const partialUser: PickPartial<
UserType,
{
email: string
address: {
coordinates: {
lat: number
lng: number
}
}
}
>
然后其他所有东西都得到一个?
可能未定义的键。有可能以某种方式做到这一点吗?
1条答案
按热度按时间jdgnovmf1#
首先,我倾向于使用这样的结构
其中潜在的嵌套键集由单个对象表示,拥有与您所关心的相同的嵌套键。嵌套的 values 并不重要,只要它们本身不是对象类型(否则 * 他们的 * 键将被探测)。我选择上面的
1
是因为它很短,但是你可以使用string
或者number
或者其他什么,我建议使用这种表示法是因为它一致地把键当作键,而不是有时把字符串类型当作空的。总之,使用它,我们可以写
PickPartial<T, K>
,就像首先,
Partial<Omit<T, keyof M>>
意味着T
中没有M
中的键的任何部分(使用Omit<T, K>
实用程序类型)将成为部分(使用Partial<T>
实用程序类型)。然后,{ [K in keyof T & keyof M]: M[K] extends object ? PickPartial<T[K], M[K]> : T[K] }
maps也在M
中的T
的密钥以及递归地PickPartial
的它们(如果Map值类型本身是一个对象)或仅保留T
中的类型(如果Map值类型不是对象,如上面的1
)。这是可行的,但会产生难以检查的类型:
你想要这种人吗?很难说。
为了弥补这一点,我将使用How can I see the full expanded contract of a Typescript type?中的一种技术,即获取基本类型,通过条件类型推理将其复制到新的类型参数中,然后在其上进行标识Map。
你可以得到更好的结果
因此,我们得到:
现在,如果我们尝试一下,我们会得到:
你想要的那种。
Playground代码链接