原始

时间:2017-06-02 11:48:01

标签: javascript string flowtype

我正在寻找将字符串用法分离为已翻译邮件和文字文本值的标识符的最佳解决方案。

所以我可能有一个名为title的对象字段,在这种情况下,它指的是表单的标题,它将具有值SIGNUP_FORM_TITLEMAIL_FORM_TITLE所以它将引用一个本地化的字符串,将传递给像format(id)这样的函数,它返回当前语言环境的实际本地化文本。

但是我可能还有一个对象字段name,它引用了一个人的姓名并且没有本地化,所以它可能具有值John Doe

当我将名称传递给格式(id)时,如何确保我收到类型错误,反之亦然当我将title传递给需要普通(文本)字符串的API时。

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

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

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

有一个related question和一个proposal可以为typescript添加类似的功能。 当然,在flowtype上选择typescript不是一种选择。

2 个答案:

答案 0 :(得分:3)

我认为您可能正在寻找的是Flow opaque type aliases

您可以创建一个opaque类型别名: opaque type LocalizationIdentifierType = string

这将作为文件中的字符串,但作为文件外的标称类型。

你提到你想要类似于LocalizationIdentifierType extends String的东西 - 你可以通过在你的opaque类型别名上添加一个子类型约束来实现这个目的:

opaque type LocalizationIdentifierType: string = string

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

答案 1 :(得分:1)

文字类型几乎可以工作。您可以将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"
};