我需要一个Partial<T>类似的映射类型,使我可以将可空字段设为可选。我正在输入ORM,它在可为空的字段上将undefined强制为null。
我想采取一种
interface User {
email: string
name: string | null
}
Run Code Online (Sandbox Code Playgroud)
和做
interface User {
email: string
name?: string | null
}
Run Code Online (Sandbox Code Playgroud)
我试过了
type NullablePartial<T> = { [P in keyof T]: T[P] extends null ? T[P] | undefined : T[P] }
Run Code Online (Sandbox Code Playgroud)
但是extends null不适用于null和的另一种类型的联合(我理想上希望它可以与字符串一起使用)。可选字段和未定义值之间的区别很重要。
我能做什么?
Kar*_*ski 10
让我们首先查找哪些属性可为空。
type NullablePropertyOf<T> = {
[K in keyof T]: null extends T[K]
? K
: never
}[keyof T]
Run Code Online (Sandbox Code Playgroud)
我们需要修改可为 null 的属性,但保持其余属性不受影响。为了在我们的转换中忽略不可空的,我们将需要众所周知的Omit助手。
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
Run Code Online (Sandbox Code Playgroud)
我们的最终产品是通过将整体的弱T部分版本与应该不受影响的属性合并而创建的。
type NullablePartial<T> = Partial<T> & Omit<T, NullablePropertyOf<T>>;
Run Code Online (Sandbox Code Playgroud)
当然,有不止一种方法可以做到这一点。在此示例中,我对所有内容进行可选化并要求所需内容。您可以采取相反的方法:首先选择不可为空的字段,然后选择可为空的字段,然后合并两种类型。无论你适合什么。
在TypeScript中,使类型函数仅将某些属性变为可选或非可选实际上是很烦人的,因为没有简单的方法来描述它。我想到的最简单的方法是使用带有交集的多个映射类型。只要您传入的类型没有索引签名(这会变得更加复杂),这应该可以工作:
type NullablePartial<
T,
NK extends keyof T = { [K in keyof T]: null extends T[K] ? K : never }[keyof T],
NP = Partial<Pick<T, NK>> & Pick<T, Exclude<keyof T, NK>>
> = { [K in keyof NP]: NP[K] }
Run Code Online (Sandbox Code Playgroud)
请注意,我使用Pick并Exclude瓜分T成空的属性和非空的属性,做不同的事情,他们每个人,然后交叉他们重新走到一起。确定可为空的属性与检查是否null extends T[K](即“我可以分配null给该属性”)有关,而不是与之相反(即“我可以将此属性分配给类型为变量的变量”)null ”)。
我还使用通用参数默认值来简化类型操作(因此,我只需确定一次可为空的属性键名称即可)NP),并使最终输出类型在美学上更为令人满意(最后通过执行一种最终的映射类型)我得到一个不表示为交集的类型。
让我们试一下:
interface User {
email: string
name: string | null
}
type NPUser = NullablePartial<User>;
// type NPUser = {
// name?: string | null | undefined;
// email: string;
// }
Run Code Online (Sandbox Code Playgroud)
在我看来合理...这接近您想要的吗?祝好运。
| 归档时间: |
|
| 查看次数: |
72 次 |
| 最近记录: |