Typescript允许您使用-?
Map类型修饰符删除“可选性”(?)
,可以轻松地与Required<T>
类型一起使用。
type Required<T> = { [P in keyof T]-?: T[P] };
但是,在使用--strictNullChecks
时(就像我一样),注意following是很重要的。
请注意,在--strictNullChecks模式下,当同态Map类型删除一个?修饰符,它也会从该属性的类型中删除undefined:
我正在寻找一种方法来绕过这种副作用
即,我想删除?
,但如果|undefined
存在,我想保留它
为什么?
我有服务器生成的接口,这些接口具有可选的(?
)属性。我想重构我的服务器代码并添加/删除成员。因此,我想要一种方法,这样我就必须为每个属性显式地设置一个值(或显式地设置为undefined
),无论是否需要。
两难:
- 如果我使用
Required<T>
,那么它会吞下我的| undefined
,但前提是存在?
。
因此,以下内容非常具有讽刺意味:
export type RequiredDog = Required <{
bark: 'loud' | 'quiet' | undefined,
bite?: 'nip' | 'clamp' | undefined
}>;
实际上变成了这样:
type RequiredDog = {
bark: "loud" | "quiet" | undefined;
bite: "nip" | "clamp";
}
所以bite
比bark
更可选,现在实际上更少可选!
有没有一种方法可以删除?
而不同时删除undefined
?
3条答案
按热度按时间uqdfh47h1#
如果我试图实现一个不剥离
undefined
属性的Required<>
,我可能会这样做:我在这里对一堆Map类型和条件类型所做的是将值类型 Package 在一个元组中,使其成为
Required
,然后展开一个元组。这在精神上与您的答案类似,但它不会与如果有人在属性中使用"undefined"
作为字符串文字发生冲突。你可以看到它的行为如你所愿:
你可以把它想象成下面的转换
{bark: "loud" | "quiet" | undefined, bite?: "nip" | "clamp" | undefined}
{bark: ["loud" | "quiet" | undefined], bite?: ["nip" | "clamp" | undefined] | undefined}
{bark: ["loud" | "quiet" | undefined], bite: ["nip" | "clamp" | undefined]}
{bark: "loud" | "quiet" | undefined, bite: "nip" | "clamp" | undefined}
好吧,希望能帮上忙;祝你好运!
链接到代码
bxfogqkk2#
我仍然喜欢更干净的解决方案,但以下方法似乎有效:
我基本上创建了一个名为
'undefined'
的类型,我用以下两个替换/取消替换真实的的undefined
类型:如果我有:
那么
WrapUndefined<Person>
就是然后你可以调用
Required<T>
来得到这个:然后用
UnwrapUndefined<T>
将其反转,得到然后我创建一个类型来完成所有这些:
如果我在问题的原始
Dog
类型上运行这个,我就得到了我想要的:这是什么
string | undefined
,因为它似乎将'undefined'吸收到string
中。幸运的是,当你运行所有三个步骤时,它最终会得到正确的结果。gmxoilav3#
下面是@Simon_Weaver答案的重构。
使用唯一的符号类型来标记
undefined
s可使其免受冲突。将其分解为更多的助手使其不言自明。
Playground