Flowtype 标称类型
Flowtype nominal typing for primitive
我正在寻找最好的解决方案,以将字符串用作已翻译消息和文字文本值的标识符。
所以我可能有一个名为 title
的 object 字段,在本例中它指的是表单的标题,它的值为 SIGNUP_FORM_TITLE
或 MAIL_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
我正在寻找最好的解决方案,以将字符串用作已翻译消息和文字文本值的标识符。
所以我可能有一个名为 title
的 object 字段,在本例中它指的是表单的标题,它的值为 SIGNUP_FORM_TITLE
或 MAIL_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