在打字稿中,我可以使用键列表从对象中删除未定义和空类型吗?

In typescript, can I remove the undefined and null types from an object using a list of keys?

我创建了一个函数来执行检查 null 和 undefined 是否为真的运行时要求:

 function hasFields<T>(obj: T | T[], ...fields: (keyof T)[]): boolean {
    const inObj: { (obj: T): boolean } = (obj) => fields.every((f) => obj[f] != null);

    if (Array.isArray(obj)) {
        return obj.every((o) => inObj(o));
    } else {
        return inObj(obj);
    }
}

但我真正想要的是 return 具有更新类型的对象,或者能够在 if 语句中使用它并能够在if 语句。

我见过这样的问题: 但它不会对字段列表执行此操作。

如果有帮助,这些字段在编译时已知。

类型 RequireAndNotNullSome 也可用于您的用例。要将 hasFields 转换为类型保护,您需要添加一个类型参数(我们称之为 K)以捕获调用函数时使用的实际键。此外,为了让它同时适用于数组和对象类型,您需要为这些案例单独重载:



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>

function hasFields<T, K extends keyof T>(obj: Array<T | RequireAndNotNullSome<T, K>>, ...fields: K[]): obj is Array<RequireAndNotNullSome<T, K>>
function hasFields<T, K extends keyof T>(obj: T | RequireAndNotNullSome<T, K> , ...fields: K[]): obj is RequireAndNotNullSome<T, K>
function hasFields<T, K extends keyof T>(obj: T | Array<T>, ...fields: K[]): boolean{
    const inObj: { (obj: T | RequireAndNotNullSome<T, K>): boolean } = (obj) => fields.every((f) => obj[f] != null);

    if (Array.isArray(obj)) {
        return obj.every((o) => inObj(o));
    } else {
        return inObj(obj);
    }
}

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

declare var v: Question;

if (hasFields(v, "answer", "thirdProp")) {
  v.answer.anchor // string 
}

declare var arr: Question[];

if (hasFields(arr, "answer", "thirdProp")) {
  arr[0].answer.anchor // string 
}

Playground Link