如何使用 TypeScript 确保两个对象具有相同的结构(无接口)?

How to use TypeScript to make sure two objects have a same structure (without interface)?

我目前正在从事一个大量使用国际化 (i18n) 的 Web 项目,我很难弄清楚如何确保所有语言共享完全相同的密钥。

这里有一个 src/lang/en.ts 文件的简单示例:

export default {
  title: "My Website Project",
  description: "This is an example of a file which contains phrases and their keys",
  hello: "Hello!",
};

这里是 src/lang/id.ts 文件的简单示例:

export default {
  title: "Proyek Website Saya",
  description: "Ini adalah contoh dari sebuah file yang mengandung beberapa frasa beserta kata kuncinya",
  hello: "Halo!",
};

现在,我希望 TypeScript 确保这些文件具有相同的键(不多也不少)。因此,如果我将 cat 属性 放入 src/lang/id.ts,则:

export default {
  title: "Proyek Website Saya",
  description: "Ini adalah contoh dari sebuah file yang mengandung beberapa frasa beserta kata kuncinya",
  hello: "Halo!",
  cat: "Kucing", // <-- this must be error because "cat" doesn't exist in en.ts file!
};

但我无法构建这样的界面

export default interface LanguageStruct {
  title: string,
  description: string,
  hello: string,
};

因为在实际项目中每种语言都有数百个短语,一个一个地编写这些键既费时又费力。我想知道是否有使用 TypeScript 来解决这个问题的技巧,或者至少有某种自动化来完成这项工作。

使用keyof typeof someObject从对象的键构造类型(例如第一语言字符串)。然后使用 Record 限制您的其他对象(其他语言)将该类型作为键,并将字符串作为值。所以你要找的类型是Record<keyof typeof someObject, string>。示例:

const en = {
  title: "My Website Project",
  description: "This is an example of a file which contains phrases and their keys",
  hello: "Hello!",
};

const de: Record<keyof typeof en, string> = {
  title: "Proyek Website Saya",
  description: "Ini adalah contoh dari sebuah file yang mengandung beberapa frasa beserta kata kuncinya",
  hello: "Halo!",
  cat: "Kucing", // this is highlighted as an error
};

查看工作示例 here