在 TypeScript 中选择嵌套字段,同时保持可选性/可空性

问题描述 投票:0回答:1

我的问题与this非常相似,但我的问题有点棘手,因为我想保留空字段和可选字段。

假设我有一个运送页面的 GraphQL 查询,如下所示:

query getShippingData() {
  myData {
    address {
      country {
        twoDigitsCode
      }
    }
  }
}

我有一个包含 GraphQL 端点生成的所有可能接口的生成文件:

interface GQLUserData {
  id: string;
  email?: null | string;
  address?: null | GQLUserAddress;
}

interface GQLUserAddress {
  street: string;
  city: string;
  state: string;
  country?: null | GQLCountry;
}

interface GQLCountry {
  id: string;
  name: string;
  available: boolean;
  twoDigitsCode?: null | string;
}

但是我不能只导入和使用整个 GQLCountry,因为它包含我在查询中没有要求的其他几个属性。

如何使用生成的对我有利的类型文件来完成下面的界面?

interface ShippingDataResponse {
  myData: {
    address?: null | {
      country?: null | {
        twoDigitsCode?: null | string;
      }
    }
  }
}

我链接的类似问题通过使用

Pick
类型实用程序并重新声明选取的字段和嵌套选取的接口来解决它。

interface ShippingDataResponse {
  myData: {
    address: {
      country: Pick<GQLCountry, 'twoDigitsCode'>;
    }
  }
}

虽然这看起来完全符合我的要求,但这实际上是将

address
country
重新声明为非可选和不可空字段,并且会导致错误的接口,如下所示:

interface ShippingDataResponse {
  myData: {
    address: {
      country: {
        twoDigitsCode?: null | string;
      }
    }
  }
}

这完全消除了

address
country
的可空性/可选性。

为了解决这个问题,我必须进入生成的类型文件,查看哪些字段是可选的或可为空的,并手动将它们标记为如此。

这首先使生成的类型文件的全部意义失效,因为它是 4K LOC 文件,并且可能会在没有任何事先通知的情况下发生更改。

我需要我的类型始终与 GraphQL 生成的值保持同步。

typescript nested
1个回答
0
投票

DeepPick<Type, Filter>
来自 ts-essentials 通过选择一组属性来构造一个类型,这些属性在类型
true
中具有来自类型
Filter
的属性值
Type

用法如下:

import { DeepPick } from 'ts-essentials';

type InitialShippingResponse = DeepPick<
  { myData: GQLUserData },
  {
    myData: {
      address: {
        country: {
          twoDigitsCode: true
        }
      }
    }
  }
>;

type InitialShippingResponse = {
myData: {
address?: {
country?: {
twoDigitsCode?: string | null | undefined;
} | null | undefined;
} | null | undefined;
};
}

© www.soinside.com 2019 - 2024. All rights reserved.