Flowtype 标称类型

Flowtype nominal typing for primitive

我正在寻找最好的解决方案,以将字符串用作已翻译消息和文字文本值的标识符。

所以我可能有一个名为 title 的 object 字段,在本例中它指的是表单的标题,它的值为 SIGNUP_FORM_TITLEMAIL_FORM_TITLE 所以它将引用一个本地化的字符串,并将传递给像 format(id) 这样的函数,其中 returns 当前语言环境的实际本地化文本。

但是我可能还有一个 object 字段 name,它指的是一个人的名字并且没有本地化,所以它可能有值 John Doe.

当我将 name 传递给 format(id) 时如何确保出现类型错误,当我将 title 传递给需要纯文本(文本)的 API 时反之亦然字符串。

我不能(当然)只说 type LocalizationIdentifierType = string 因为这只是一个别名。

也许我可以创建字符串 class LocalizationIdentifier extends String 的子类,但这仍然允许 LocalizationIdentifier 传递给基于 API 的字符串(或者至少我认为是这样) .

有没有人有更好的办法来名义上键入字符串? 或者也许我完全走错了路? ("Auf dem Holzweg" 正如我们在德国所说)


有一个 related question and a proposal 可以为打字稿添加类似的功能。 选择 typescript 而不是 flowtype 当然不是一种选择。

文字类型几乎可以工作。您可以将 format 的签名指定为

function format(id: "SIGNUP_FORM_TITLE" | "MAIL_FORM_TITLE" | ...): string {
   ...
}

不幸的是,这对于您的其他情况来说是分崩离析的(本地化文本错误地传递给了纯文本 API)。对象文字类型看起来像 JavaScript 阻力最小的路径:

type LocalizedString = {
  +field: "SIGNUP_FORM_TITLE" | "MAIL_FORM_TITLE"
};
type PlainText = string;

const signupFormTitle: LocalizedString = { field: "SIGNUP_FORM_TITLE" };
const mailFormTitle: LocalizedString = { field: "MAIL_FORM_TITLE" };

如果您需要在 LocalizedString 上引入变体,对象中的附加标记字段效果很好,例如:

type LocalizedString = {
  +variant: "variant1",
  +field: "SIGNUP_FORM_TITLE" | "MAIL_FORM_TITLE"
};

我想您可能正在寻找 Flow 的 opaque type aliases

您可以制作一个不透明的类型别名: opaque type LocalizationIdentifierType = string

这在文件内表现为字符串,但在文件外表现为标称类型。

你提到你想要类似于 LocalizationIdentifierType extends String 的东西——你可以通过在你的不透明类型别名上添加子类型约束来实现:

opaque type LocalizationIdentifierType: string = string

这意味着一个LocalizationIdentifierType是一个字符串,但并不是所有的字符串都是一个LocalizationIdentifierType