从类型的属性中删除 null 或 undefined
Posted
技术标签:
【中文标题】从类型的属性中删除 null 或 undefined【英文标题】:remove null or undefined from properties of a type 【发布时间】:2019-04-02 15:37:44 【问题描述】:我需要声明一个类型,以便从其属性类型中删除 undefined。
假设我们有:
type Type1
prop?: number;
type Type2
prop: number | undefined;
type Type3
prop: number;
我需要定义一个名为NoUndefinedField<T>
的泛型类型,以便NoUndefinedField<Type1>
提供与Type3
相同的类型以及与NoUndefinedField<Type2>
相同的类型。
我试过了
type NoUndefinedField<T> = [P in keyof T]: Exclude<T[P], null | undefined> ;
但它只适用于Type2
。
【问题讨论】:
Type1 你需要to remove optional modifier 很棒的@artem,这正是我想要的。 【参考方案1】:有些答案对我不起作用,我最终得到了基于最佳答案的类似解决方案:
type RequiredNonNullableObject<T extends object> = [P in keyof Required<T>]: NonNullable<T[P]>; ;
这会导致以下结果:
type ObjectType =
startDateExpr?: string | null;
endDateExpr?: string | null;
startDate?: Date | null;
endDate?: Date | null;
type Result = RequiredNonNullableObject<ObjectType>;
Result
类型等于:
type Result =
startDateExpr: string;
endDateExpr: string;
startDate: Date;
endDate: Date;
TypeScript Playground Example
【讨论】:
【参考方案2】:现在还内置了 NonNullable
类型:
type NonNullable<T> = Exclude<T, null | undefined>; // Remove null and undefined from T
https://www.typescriptlang.org/docs/handbook/utility-types.html#nonnullablet
【讨论】:
很遗憾,如果您没有启用--strictNullChecks
,它不会从类型中排除null
...【参考方案3】:
@Fartab 和 @tim.stasse 的答案中的某些内容对我来说是搞砸了 Date
类型的属性:
// both:
type NoUndefinedField<T> =
[P in keyof T]-?: NoUndefinedField<NonNullable<T[P]>>;
;
type NoUndefinedField<T> =
[P in keyof T]-?: NoUndefinedField<Exclude<T[P], null | undefined>>;
;
// throw:
Property '[Symbol.toPrimitive]' is missing in type 'NoUndefinedField<Date>' but required in type 'Date'.ts(2345)
// and
type NoUndefinedField<T> = [P in keyof T]: Required<NonNullable<T[P]>> ;
// throws:
Property '[Symbol.toPrimitive]' is missing in type 'Required<Date>' but required in type 'Date'.ts(2345)
我在没有递归的情况下成功地使用了这个解决方案:
type NoUndefinedField<T> =
[P in keyof T]-?: Exclude<T[P], null | undefined>;
;
【讨论】:
谢谢,这很好用。在使用用户定义的属性类型时,我在使用其他答案时也遇到了问题。【参考方案4】:感谢@artem,解决方案是:
type NoUndefinedField<T> = [P in keyof T]-?: NoUndefinedField<NonNullable<T[P]>> ;
注意[P in keyof T]-?
中的-?
语法,它删除了可选性
【讨论】:
这正是我所期望的答案,过滤了现有的界面。谢谢! 非常感谢。我想知道-?
是什么。你在哪里找到这个规范?我总是先看 TS 的文档,但我觉得找东西不容易。
嗨尼古拉斯。是的,这很难找到。两年前,@artem 告诉我存在这样的运营商。
缺少一些东西,我得到了Type 'NoUndefinedField<Uint8Array>' is missing the following properties from type 'Uint8Array': [Symbol.iterator], [Symbol.toStringTag]
——这个有效:***.com/a/61766383/544779【参考方案5】:
@DShook 的回答不正确(或者说不完整),因为 OP 要求从类型属性中删除 null 和 undefined,而不是从类型本身(明显不同)。
虽然@Fartab 的回答是正确的,我补充一下,因为现在有内置的Required
类型,解决方案可以重写为:
type RequiredProperty<T> = [P in keyof T]: Required<NonNullable<T[P]>>; ;
这将映射类型属性(而不是类型本身),并确保每个都不是; null 或未定义。
从类型中删除 null 和 undefined 与从类型属性中删除它们的区别示例(使用上面的 RequiredProperty
类型):
type Props =
prop?: number | null;
;
type RequiredType = NonNullable<Props>; // prop?: number | null
type RequiredProps = RequiredProperty<Props>; // prop: Required<number> = prop: number
【讨论】:
重写的解决方案不会是递归的,对吧?以上是关于从类型的属性中删除 null 或 undefined的主要内容,如果未能解决你的问题,请参考以下文章