从类型的属性中删除null或undefined

Far*_*tab 4 null types undefined typescript

我需要声明一个类型,以便从其属性类型中删除未定义的类型。

假设我们有:

type Type1{
  prop?: number;
}

type Type2{
  prop: number | undefined;
}

type Type3{
  prop: number;
}
Run Code Online (Sandbox Code Playgroud)

我需要定义一个称为的通用类型NoUndefinedField<T>,以NoUndefinedField<Type1>提供与相同的类型Type3和与相同的类型NoUndefinedField<Type2>

我试过了

type NoUndefinedField<T> = { [P in keyof T]: Exclude<T[P], null | undefined> };
Run Code Online (Sandbox Code Playgroud)

但这仅适用于Type2

Far*_*tab 24

感谢@artem,解决方案是:

type NoUndefinedField<T> = { [P in keyof T]-?: NoUndefinedField<NonNullable<T[P]>> };
Run Code Online (Sandbox Code Playgroud)

注意删除可选性的-?语法[P in keyof T]-?


小智 17

现在你可以使用 required 来完成你需要的事情:

Required<Type1>
Run Code Online (Sandbox Code Playgroud)

这将导致所有字段都变为非可选字段。更多详情可在这找到


DSh*_*ook 11

现在还有NonNullable内置的类型:

type NonNullable<T> = Diff<T, null | undefined>;  // Remove null and undefined from T
Run Code Online (Sandbox Code Playgroud)

https://www.typescriptlang.org/docs/handbook/utility-types.html#nonnullablet

  • 否决是因为这会从类型本身中删除“null”和“undefined”,而不是从其属性中删除,不是吗?因此它没有回答这个问题。 (9认同)

小智 8

@DShook 的答案是不正确的(或者说是不完整的),因为 OP 要求从类型属性中删除 null 和 undefined,而不是从类型本身中删除(明显的区别)。

虽然@Fartab 的答案是正确的,但我会补充它,因为现在有内置Required类型,并且解决方案可以重写为:

type RequiredProperty<T> = { [P in keyof T]: Required<NonNullable<T[P]>>; };
Run Code Online (Sandbox Code Playgroud)

这将映射类型属性(不是类型本身),并确保每个属性都不是;空或未定义。

从类型中删除 null 和 undefined 与从类型属性中删除它们之间的区别示例(使用上述RequiredProperty类型):

type Props = {
  prop?: number | null;
};

type RequiredType = NonNullable<Props>; // { prop?: number | null }
type RequiredProps = RequiredProperty<Props>; // { prop: Required<number> } = { prop: number }
Run Code Online (Sandbox Code Playgroud)


Rob*_*ina 6

有些答案对我不起作用,我最终根据最重要的答案得到了类似的解决方案:

type RequiredNonNullableObject<T extends object> = { [P in keyof Required<T>]: NonNullable<T[P]>; };
Run Code Online (Sandbox Code Playgroud)

结果如下:

type ObjectType = {

  startDateExpr?: string | null;
  endDateExpr?: string | null;

  startDate?: Date | null;
  endDate?: Date | null;

}

type Result = RequiredNonNullableObject<ObjectType>; 

Run Code Online (Sandbox Code Playgroud)

类型Result等于:

type Result = {
  startDateExpr: string;
  endDateExpr: string;
  startDate: Date;
  endDate: Date;
}
Run Code Online (Sandbox Code Playgroud)

TypeScript Playground 示例

  • 我正在寻找一种解决方案,使类型的所有属性都不可为空。这有效,谢谢 (2认同)

Ste*_*pan 5

@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)
Run Code Online (Sandbox Code Playgroud)

我在没有递归的情况下成功使用了这个解决方案:

type NoUndefinedField<T> = {
  [P in keyof T]-?: Exclude<T[P], null | undefined>;
};
Run Code Online (Sandbox Code Playgroud)