两个独立的接口或一个扩展的接口:干燥或不干燥

时间:2016-12-15 11:45:50

标签: inheritance typescript interface redux state

从无类型语言JavaScript到类型化TypeScript,您开始使用接口。有时候关于如何构建应用程序的简单问题变成与我的团队成员的暴力讨论:)我们正在构建React + Redux + TypeScript应用程序,我们有两个“东西”:用户的应用程序状态(用户) Redux商店内的表示)和用户的API响应(描述JSON API响应),它们都有接口,截至目前,它们都是相同的,但这可能会改变。映射是使用一些自定义函数完成的:

const mapUserApiToState = (user: IUserAPI): IUserState => { ... }

由于这是一个早期阶段,并且会有大量的接口要写,我们可以采取两种或三种路径:

(1)将每个界面分别放入各自的文件。但是你必须为违反DRY原则的每个接口重复相同的属性。

// file1.ts
interface IUserState {
  id: number;
  name: string;
  kids: number;
}

// file2.ts
interface IUserAPI {
  id: number;
  name: string;
  kids: number;
}

(2)只需将一个界面扩展为另一个界面。这样你就不需要重复自己,但是这意味着一个界面扩展另一个界面,而实际上它们看起来是一样的,但是用于完全不同的目的

// file1.ts
interface IUserState {
  id: number;
  name: string;
  kids: number;
}

// file2.ts
interface IUserAPI extends IUser {}

(3)创建第三个抽象接口。但是这会创建一个带有不应该使用的接口的文件(你在哪里使用IUser?)

// file1.ts
interface IUser {
  id: number;
  name: string;
  kids: number;
}

// file2.ts
interface IUserState extends IUser {}

// file3.ts
interface IUserAPI extends IUser {}

(4)放弃琐碎事情的时间。 YAGNI。

1 个答案:

答案 0 :(得分:0)

经过多次辩论后,我们决定使用TypeScript的typeof功能并决定复制变量的枚举,但我们使用默认应用程序状态的值作为我们类型的定义,而不是使用两个接口。所以它与两个接口不一样,但确实更有意义。

interface IUserAPI {
    id: number;
    name: string;
    kids: number;
}

const defaultUserState = {
    id: 0,
    name: "Unnamed",
    kids: 0
}

type IUserState = typeof defaultUserState