属性 'VAR_PLURAL' 类型不存在

Property 'VAR_PLURAL' does not exist on type

使用 angular 8.x i18n 我遇到了一个错误消息非常模糊的问题(因为所有 i18n 错误消息往往都是;看着你,https://github.com/angular/angular-cli/issues/7555#issuecomment-394228634) .

消息指出:ERROR in src/app/***.component.html(1,2): : Property 'VAR_PLURAL' does not exist on type '***Component'.

该错误仅正确说明了哪个文件受到影响,但行指示符是无意义的。使用二进制搜索,评论了一半的 i18n 复数出现,我设法查明了麻烦制造者:

<ng-container i18n="@@playerCardinality">
  {singleTournament.tournament.teamSize.max, plural, =1 {player} other {players}}
</ng-container>

起初我认为问题可能是变量名称不同,因为这个 @@playerCardinality 在整个应用程序的多个地方使用:

<ng-container i18n="@@playerCardinality">{ tournamentScreen.tournament.teamSize.max, plural, =1 {player} other {players} }</ng-container>
<ng-container i18n="@@playerCardinality">{ ladderScreen.ladder.teamSizeMax, plural, =1 {player} other {players} }</ng-container>

但其他的也没有相同的变量名,到目前为止没有问题。

注释掉那些其他事件也解决了这个问题,所以它一定是这些事件之间的某种交互相关问题。

一定是一些平庸的问题,因为显然没有其他人遇到过类似的问题(基于 google 结果)...

找到答案,可能与谁有关,问题出在格式上,当我删除换行符时它起作用了。所以基本上所有具有相同id的翻译都必须具有相同的格式以及相同的内容。

这些是工作翻译:

<ng-container i18n="@@playerCardinality">{ singleTournament.tournament.teamSize.max, plural, =1 {player} other {players} }</ng-container>
<ng-container i18n="@@playerCardinality">{ tournamentScreen.tournament.teamSize.max, plural, =1 {player} other {players} }</ng-container>
<ng-container i18n="@@playerCardinality">{ ladderScreen.ladder.teamSizeMax, plural, =1 {player} other {players} }</ng-container>

我知道作者已经找到了自己的解决方案,但我将详细说明并列出更多可能发生此错误的场景以及如何修复它们。此修复也适用于 VAR_SELECT 和 VAR_PLURAL。因此,如果您看到此错误:ERROR in src/app/app.component.html(1,2): Property 'VAR_SELECT' does not exist on type 'AppComponent'. 以下修复也应该对您有所帮助。

如果你有以下翻译:

<trans-unit id="PLURAL_TEST" datatype="html">
  <source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
  <target>{VAR_PLURAL, plural, =0 {à l'instantt} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes} }</target>
</trans-unit>

并且想在您的 html 中使用它,您可以这样做:

<p i18n="@@PLURAL_TEST">{minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }</p>

但是,如果您在 html 的 {minutes, plural ...} } 部分之前或之后有一些字符,它将失败并且您将看到此错误:ERROR in src/app/app.component.html(1,8): Property 'VAR_PLURAL' does not exist on type 'AppComponent'.

这意味着以下所有 html 值都将失败:

<p i18n="@@PLURAL_TEST"> {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }</p>
<p i18n="@@PLURAL_TEST">{minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} } </p>
<p i18n="@@PLURAL_TEST">
{minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }
</p>

第一个开头有一个space,第二个结尾有一个space,第三个有一个换行符。第三个是原始发布者所做的示例。你可以用任何字符、单词、插值等替换 whitespace,它总是会失败。即使您更改 .xlf 文件中的翻译以匹配 html,它仍然会失败。例如:

xlf:

<trans-unit id="PLURAL_TEST" datatype="html">
  <source> {VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
  <target> {VAR_PLURAL, plural, =0 {à l'instantt} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes} }</target>
</trans-unit>

html:

<p i18n="@@PLURAL_TEST"> {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }</p>

还是会失败。尽管前导 space 存在于翻译中,而 html.

如果您确实想将 VAR_PLURAL 或 VAR_SELECT 翻译嵌套在另一个翻译中,那么您应该使用 <x id="ICU" /> 标签来实现。

所以如果我想在我的html中使用这个:

<p>Hello, {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }</p>

我需要定义两种翻译,一种用于文本的 VAR_PLURAL 或 VAR_SELECT 部分。我们将其称为内部翻译。我们还需要对文本的其余部分进行另一个翻译(在本例中是 Hello, 部分),这将是外部翻译。所以我的翻译文件将如下所示:

<trans-unit id="PLURAL_TEST_OUTER" datatype="html">
  <source>Hello, <x id="ICU" /></source>
  <target>Bonjour, <x id="ICU" /></target>
</trans-unit>

<trans-unit id="5a134dee893586d02bffc9611056b9cadf9abfad" datatype="html">
  <source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" /> minutes ago} }</source>
  <target>{VAR_PLURAL, plural, =0 {à l'instantt} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes} }</target>
</trans-unit>

请注意,内部表达式的 trans-id 必须自动生成(请参阅 https://github.com/angular/angular/issues/26379)。

我的 html 将如下所示:

<p i18n="@@PLURAL_TEST_OUTER">Hello, {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago} }</p>

您可以在此处找到有关嵌套翻译的更多信息 - https://angular.io/guide/i18n#translate-a-nested-expression

总而言之,如果您遇到此问题:

  1. 在 html 中的 VAR_PLURAL 或 VAR_SELECT 语句之前或之后检查白色 space、字符或插值。如果它不应该存在,请将其删除。
  2. 如果它应该存在,请确保您正确地将翻译嵌套在 .xlf 文件中。