规范化数据的 TypeScript 类型或接口

TypeScript Type or Interface for Normalized Data

TLDR:如何为标准化数据创建接口?

我正在使用 TypeScript 构建一个 React 应用程序。我使用 Normalizr 规范化来自 API 调用的数据。

举文档中的示例,API 响应如下:

快速入门 考虑一个典型的博客 post。单个 post 的 API 响应可能如下所示:

{
  "id": "123",
  "author": {
    "id": "1",
    "name": "Paul"
  },
  "title": "My awesome blog post",
  "comments": [
    {
      "id": "324",
      "commenter": {
        "id": "2",
        "name": "Nicole"
      }
    }
  ]
}

可能会归一化为:

{
  result: "123",
  entities: {
    "articles": {
      "123": {
        id: "123",
        author: "1",
        title: "My awesome blog post",
        comments: [ "324" ]
      }
    },
    "users": {
      "1": { "id": "1", "name": "Paul" },
      "2": { "id": "2", "name": "Nicole" }
    },
    "comments": {
      "324": { id: "324", "commenter": "2" }
    }
  }
}

我想为使用 Normalizr 的函数创建接口。这是我到目前为止尝试过的方法:

export interface House {
  uuid: string;
  address: string;
}

export interface Citizen {
  uuid: string;
  name: string;
}

export interface NormalizedData<T> {
  [uuid: string]: T;
}

export interface Entity<T> {
  [name: string]: NormalizedData<T>;
}

export interface NormalizerResult<T> {
  result: any;
  entities: Entity<T>;
}

由于我这里必须给出泛型类型T,所以这种方式只能处理一个实体。问题是实体键可以有多个不同类型的实体,例如。 House and Citizen(以及更多)。我该如何解释呢? Normalizr 自己的类型只是返回 { result: any, entities: any }.

我猜你想要这样的东西

export interface NormalizerResult<T extends House | Citizen> {
  result: any;
  entities: Entity<T>;
}

P.S。当你 100% 知道响应的结构时,Typescript 更有用,如果每次响应都不同,Typescript 就没那么有用了。如果前者是正确的,那么您应该为每个响应创建类型,例如

export interface NormalizerResultForHousesAndCitizensRequest {
  result: any;
  entities: {
    houses: NormalizedData<House>,
    citizens: NormalizedData<Citizen>,
  };
}