typescript 是否可以从现有接口创建一个新接口,并根据条件删除某些顶级属性?

ippsafx7  于 2023-05-23  发布在  TypeScript
关注(0)|答案(1)|浏览(188)

我有以下接口:

interface Example {
  '/api/good/path': {
    get: Record<string, unknown>;
    parameters: Record<string, unknown>;
  };
  '/api/alsogood/path': {
    get: Record<string, unknown>;
  };
  '/api/bad/path': {
    post: Record<string, unknown>;
  };
  '/api/technicallygood/path': {
    get: Record<string, unknown>;
    post: Record<string, unknown>;
  };
}

是否可以从Example创建一个新接口,但删除所有不包含get属性的嵌套对象?
我的目标是最终得到这样的东西:

interface Example {
  '/api/good/path': {
    get: Record<string, unknown>;
    parameters: Record<string, unknown>;
  };
  '/api/alsogood/path': {
    get: Record<string, unknown>;
  };
  '/api/technicallygood/path': {
    get: Record<string, unknown>;
    post: Record<string, unknown>;
  };
}

换句话说,由于Example['/api/bad/path']不包含get,因此将其删除。Example的所有其他键都保留,因为它们至少包含一个名为get的属性。

toiithl6

toiithl61#

这可以通过使用mapped types和键重Map来实现。

type RemoveBadEndpoints<T> = {
  [K in keyof T as 'get' extends keyof T[K] ? K : never]: T[K];
};

说明:
我们通过键进行Map,如果属性具有'get'属性,我们使用K作为键,否则,never将删除此属性,因为never不能用作键,并且被视为空并集。

// type GoodEndpoints = {
//   '/api/good/path': {
//       get: Record<string, unknown>;
//       parameters: Record<string, unknown>;
//   };
//   '/api/alsogood/path': {
//       get: Record<string, unknown>;
//   };
//   '/api/technicallygood/path': {
//       get: Record<string, unknown>;
//       post: Record<string, unknown>;
//   };
// }
type GoodEndpoints = RemoveBadEndpoints<Example>;

Playground

相关问题