网站搜索

javascript - Typescript:从类型中省略 undefined/null 属性


我正在尝试从一个类型创建新类型,但移除任何值为 undefined|null 的属性,这是为了创建一个用于 fetch 的函数,该函数可以要求或不要求 payload 参数。

主要类型是:

type TEndpointsPayload = {
    getList: undefined,
    open: {
        id: string
    }
    close: {
        id: string
    }
}

当我尝试创建一个看起来像这样的新类型时:

type TEndpointsNonEmptyPayload = {
    open: {
        id: string
    }
    close: {
        id: string
    }
}

所以 getList 被省略,因为它的值是未定义的/不是一个对象。

我尝试了许多方法,包括 Omit、Exclude 等,但似乎没有一个真正从类型中移除该属性,而是将其设置为 never。

任何帮助都将不胜感激!

这个函数大致如下(假设 TEndpointsNonEmptyPayload 实际上可用):

private reuqest<T extends keyof TEndpointsNonEmptyPayload>(endpoint: T, payload: TEndpointsNonEmptyPayload[T]): void;

为了解决这个问题,我在考虑创建一些类似这样的函数重载:

private reuqest<T extends keyof TEndpointsPayload>(endpoint: T): void;

很乐意听取一些关于类型或功能实现的想法!

答案#1

下面的 OmitNullish<T> 实现会完全从映射类型中排除键,如果它们的值类型为 null|undefined,而不是将它们的值设置为 never。它符合你的需求吗?

编辑:看起来我和 Jcalz 不仅得出了相同的答案,甚至使用了相同的别名 OmitNullish<T>(如上面链接的评论所示)。英雄所见略同!

type TEndpointsPayload = {
  getList: undefined;
  open: {
    id: string;
  };
  close: {
    id: string;
  };
};

type OmitNullish<T> = {
  [K in keyof T as T[K] extends null | undefined ? never : K]: T[K];
};

type TEndpointsNonEmptyPayload = OmitNullish<TEndpointsPayload>;

答案#2

如果你需要从类型中移除可选和未定义的属性,你可以使用 NonNullable 定义 OmitNullish 类型,方法如下:

type OmitNullish<T> = {
  [K in keyof T as T[K] extends NonNullable<T[K]> ? K : never]: T[K];
};

这可以这样使用:

type MyType = {
    one?: string,
    two: number,
    three: undefined,
}

type WithoutNulls = OmitNullish<MyType>

新类型 WithoutNulls 将是:

type WithoutNulls = {
    two: number;
}

操场

相关文章