如何合并接口和变量的默认值?

How to merge an interface and default values of a variable?

我在下面有令人作呕的代码,我想在其中结合 TypeScript 类型的安全性和变量的默认值:

interface Store {
  infinoteToken: string | null,
  allNotes: Note[],
  // plenty more
}

export const store: Store = reactive({
  infinoteToken: null,
  allNotes: [],
  // plenty more
})

我最终得到了两个包含重复信息的代码块。

有没有办法将这两个元素结合起来,为其成员声明一个具有默认值和类型的对象?

这一切都可以移动到 class 默认实现:

class Store {
  infinoteToken: string | null = null;
  allNotes: Note[] = [];
  // plenty more

}

export const store = reactive(new Store());

您可以声明您的默认对象,然后从中派生类型:

const STORE_DEFAULTS = {
  infinoteToken: null as string | null,
  allNotes: [] as Note[],
  numericProperty: 1,
  booleanProperty: true,
  // plenty more
}

interface OptionalStoreProperties {
  optionalString?: string;
  // potentially more
}

type Store = typeof STORE_DEFAULTS & OptionalStoreProperties ;

Playground Link

  • numericPropertybooleanProperty 这样匹配默认值类型的简单属性将被正确推断。
  • 如果它与您分配的值不同,则必须使用 a type assertion 来覆盖类型:infinoteToken 可以是 null 或字符串,因此 as string | null 确保字符串仍然可以分配给它。
  • 空数组也总是需要进行类型断言。否则 allNotes .
  • 如果有不应该初始化的可选属性,那么您需要将它们添加到类型中。 A type intersection (&)(link是旧的TypeScript Hanbook,因为新的没有交集的解释。旧的信息仍然是相关的)将结合两种类型的属性。

话虽如此,我建议将类型和默认值分开。它可能看起来像重复代码,但实际上并非如此。

  1. 通过仅查看该信息来理解类型 更清楚,而不必在精神上区分哪个 属性 属于哪种类型(假设隐式分配。
  2. 当它们与所有其他代码分开时,更清楚默认值是什么。
  3. 如果您添加关于不同事物的评论,您所指的内容会更清楚。也许您想说为什么 选择了给定的默认值。或者,也许您想解释如何使用 属性。这些不必在同一个地方。
  4. 您还可以有多个个默认值。也许不适用于这种类型,但绝对可以根据某些条件决定默认值并仅应用那些。将类型和默认值集分开保持此选项打开并且更容易扩展更多。