打字稿类型 RequireSome从属性中删除 undefined AND null

打字稿类型 RequireSome<T, K extends keyof T>从属性中删除 undefined AND null

问题描述:

RequireSome 来自另一个非常相似的问题.这个问题很相似,但它不应该是重复的,因为在这里我们要也删除 null 以及从属性中删除 undefined.

RequireSome type from another, very simialar question. This question is similar but it should not be a duplicate since here we want to also remove null as well as undefined from properties.

也许名称不应该是 Require 而是类似 NonNullable 或此类的名称.此类型的目标是指定类型中的哪些字段不应是 undefined 或 null,并返回它们的类型,而不是 undefined 和 null.

Maybe the name shouldn't be Require but something like NonNullable or of this kind. The goal of this type is to specify which fields from a type should not be undefined or null, and return their types without undefined and null.

type Question = {
    id: string;
    answer?: string | null;
    thirdProp?: number | null;
    fourthProp?: number | null;
}

// usage NonNullable<Question, 'answer' | 'thirdProp'> expect to equal
/*

type Question = {
    id: string; // no changes
    answer: string; // changed
    thirdProp: number; // changed
    fourthProp?: number | null; // no changes
}

*/

TRequired> 相交的简化方法基本上覆盖 T 中的可选属性的必需部分在这里不起作用.(顺便说一句,这是因为 { foo?: X } & { foo: X } 本质上是 { foo: X })

The simplified approach that just intersects with T with Required<Pick<T, K>> with the required part basically overriding the optional properties in T will not work here. (Incidentally this works because { foo?: X } & { foo: X } is essentially { foo: X })

为了同时去除可空性,我们必须首先创建一个从给定类型 T 中去除 nullundefined 的类型(类似于 必填代码>).然后,我们需要使用 Omit 类型将我们想要使其成为必需且不为空的属性与 T 中的其余键相交.

To also remove nullability, we have to first create a type that removed null and undefined from a given type T (analogous to Required). Then we need to intersect the properties we want to make required and not null with the rest of the keys in T using the Omit type.

type Omit<T, K> = Pick<T, Exclude<keyof T, K>> // not needed in ts 3.5

type RequiredAndNotNull<T> = {
    [P in keyof T]-?: Exclude<T[P], null | undefined>
}

type RequireAndNotNullSome<T, K extends keyof T> = 
    RequiredAndNotNull<Pick<T, K>> & Omit<T, K>

type Question = {
    id: string;
    answer?: string | null;
    thirdProp?: number | null;
    fourthProp?: number | null;
}

type T0 = RequireAndNotNullSome<Question, 'answer' | 'thirdProp'>