# @cookbook/solid-intl 中文文档

规范地址：https://npmcn.com/package/%40cookbook/solid-intl/

版本：0\.1\.3
npm 元数据更新时间：2025-07-07T16:24:23.563Z
中文译文更新时间：2026-11-10T18:10:02.299Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40cookbook/solid-intl
原文对照：https://npmcn.com/package/%40cookbook/solid-intl/?lang=original
项目主页：https://github.com/the-cookbook/solid-intl#readme
源码仓库：https://github.com/the-cookbook/solid-intl

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：50.3 kB，21 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：1 个
- peer 依赖：solid-js \>=1\.0\.0
- 首次发布：2023-01-04T14:02:24.303Z
- 最新版本发布：2025-07-07T16:24:23.370Z
- 近 30 天下载量：6932（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：4（近 12 个月 0 个）

## 中文简介

由 React Intl & FormatJS 所启发的 Solid 通用国际化(i18n)

## 安装

```sh
npm install @cookbook/solid-intl
```

也可以使用：`pnpm add @cookbook/solid-intl`、`yarn add @cookbook/solid-intl`、`bun add @cookbook/solid-intl`

## README

![solid-intl](https://assets.solidjs.com/banner?type=solid-intl&background=tiles&project=%20)

# 固态

[![pnpm](https://img.shields.io/badge/maintained%20with-pnpm-cc00ff.svg?style=for-the-badge&logo=pnpm)](https://pnpm.io/) [![NPM Version](https://img.shields.io/npm/v/@cookbook/solid-intl.svg?style=flat-square)](https://npmjs.org/package/@cookbook/solid-intl) [![Downloads Stats](https://img.shields.io/npm/dm/@cookbook/solid-intl.svg?style=flat-square)](https://npmjs.org/package/@cookbook/solid-intl) [![GitHub stars](https://img.shields.io/github/stars/the-cookbook/solid-intl.svg)](https://github.com/the-cookbook/solid-intl/stargazers) [![Known Vulnerabilities](https://snyk.io/test/github/the-cookbook/solid-intl/badge.svg)](https://snyk.io/test/github/the-cookbook/solid-intl) [![GitHub issues](https://img.shields.io/github/issues/the-cookbook/solid-intl.svg)](https://github.com/the-cookbook/solid-intl/issues) [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/the-cookbook/solid-intl)

由React Intl & FormatJS所启发的Solid通用国际化(i18n).

## 快开始

### 安装它 :

```bash
npm i @cookbook/solid-intl
# or
yarn add @cookbook/solid-intl
# or
pnpm add @cookbook/solid-intl
```

### 用 `<IntlProvider />`

```tsx
import { IntlProvider } from '@cookbook/solid-intl'

// usersLocale = 'en', 'en-US', 'pt-BR', so on...
// translationsForUsersLocale = translations for selected locale
render(() =>
  <IntlProvider locale={usersLocale} messages={translationsForUsersLocale}>
    <App />
  </IntlProvider>,
  document.getElementById("root")!);
```

### 创建您的消息并使用它 `intl.formatMessage`

```tsx
import { defineMessages, useIntl } from '@cookbook/solid-intl';

const messages = defineMessages({
  greeting: {
    id: "app.greeting",
    defaultMessage: "Hello world!",
  },
});

function Component(props) {
  const { intl } = useIntl();

  return intl.formatMessage(messages.greeting) // outputs: Hello world!
}
```

* * *

# 目录

-   [API 密码](https://npmcn.com/package/%40cookbook/solid-intl/#readme-api)
    -   [`<IntlProvider />`](https://npmcn.com/package/%40cookbook/solid-intl/#readme-intlprovider-)
        -   [语言、格式和消息](https://npmcn.com/package/%40cookbook/solid-intl/#readme-locale-formats-and-messages)
        -   [默认本地和默认格式](https://npmcn.com/package/%40cookbook/solid-intl/#readme-defaultlocale-and-defaultformats)
        -   [默认 Rich 文本元素](https://npmcn.com/package/%40cookbook/solid-intl/#readme-defaultrichtextelements)
        -   [错误](https://npmcn.com/package/%40cookbook/solid-intl/#readme-onerror)
        -   [警告时](https://npmcn.com/package/%40cookbook/solid-intl/#readme-onwarn)
    -   [`useIntl()` 钩子](https://npmcn.com/package/%40cookbook/solid-intl/#readme-useintl-hook)
        -   [格式 日期](https://npmcn.com/package/%40cookbook/solid-intl/#readme-formatdate)
        -   [格式时间](https://npmcn.com/package/%40cookbook/solid-intl/#readme-formattime)
        -   [格式化时间](https://npmcn.com/package/%40cookbook/solid-intl/#readme-formatrelativetime)
        -   [数量](https://npmcn.com/package/%40cookbook/solid-intl/#readme-formatnumber)
        -   [格式图](https://npmcn.com/package/%40cookbook/solid-intl/#readme-formatplural)
        -   [格式列表](https://npmcn.com/package/%40cookbook/solid-intl/#readme-formatlist)
        -   [格式显示Name](https://npmcn.com/package/%40cookbook/solid-intl/#readme-formatdisplayname)
        -   [格式](https://npmcn.com/package/%40cookbook/solid-intl/#readme-formatmessage)
        -   [定义](https://npmcn.com/package/%40cookbook/solid-intl/#readme-definemessagesdefinemessage)
-   [信件提取](https://npmcn.com/package/%40cookbook/solid-intl/#readme-message-extraction)
    -   [采掘业](https://npmcn.com/package/%40cookbook/solid-intl/#readme-extraction)
-   [基本国际化原则](https://npmcn.com/package/%40cookbook/solid-intl/#readme-basic-internationalization-principles)
    -   [国际化有什么意义?](https://npmcn.com/package/%40cookbook/solid-intl/#readme-what-is-internationalization-and-why-does-it-matter)
    -   [语言和地区](https://npmcn.com/package/%40cookbook/solid-intl/#readme-locales-language-and-region)
    -   [翻译字符串](https://npmcn.com/package/%40cookbook/solid-intl/#readme-translating-strings)
-   [信件语法](https://npmcn.com/package/%40cookbook/solid-intl/#readme-message-syntax)
    -   [信件描述符](https://npmcn.com/package/%40cookbook/solid-intl/#readme-message-descriptor)
    -   [信件格式倒置](https://npmcn.com/package/%40cookbook/solid-intl/#readme-message-formatting-fallbacks)
    -   [格式化信件参数](https://npmcn.com/package/%40cookbook/solid-intl/#readme-formatting-message-argument)
        -   [`number` 格式化](https://npmcn.com/package/%40cookbook/solid-intl/#readme-number-formatting)
        -   [`date` 格式化](https://npmcn.com/package/%40cookbook/solid-intl/#readme-date-formatting)
        -   [`time` 格式化](https://npmcn.com/package/%40cookbook/solid-intl/#readme-time-formatting)
        -   [支持的日期时间 Skeleton](https://npmcn.com/package/%40cookbook/solid-intl/#readme-supported-datetime-skeleton)
        -   [`{select}` 格式](https://npmcn.com/package/%40cookbook/solid-intl/#readme-select-format)
        -   [`{plural}` 格式](https://npmcn.com/package/%40cookbook/solid-intl/#readme-plural-format)
        -   [`{selectordinal}` 格式](https://npmcn.com/package/%40cookbook/solid-intl/#readme-selectordinal-format)
        -   [丰富文本格式](https://npmcn.com/package/%40cookbook/solid-intl/#readme-rich-text-formatting)
        -   [引用/出逃](https://npmcn.com/package/%40cookbook/solid-intl/#readme-quoting--escaping)

* * *

# API 密码

## `<IntlProvider />`

Solid Intl使用提供商模式将一i18n上下文范围到一棵组件树上. 这样可以像当前地块和被翻译的字符串/消息集这样的配置在组件树的根上提供,并提供给"使用Intl ()"的钩子方法. 此组件用于为一棵树设置i18n上下文. 通常,这个组件会包起一个app的根组件,这样整个app就会在所配置的i18n上下文内. 以下为可以设置的i18n配置道具:

```tsx
interface IntlConfig {
  locale: Locale;
  timeZone?: string;
  fallbackOnEmptyString?: boolean;
  formats?: CustomFormats;
  messages: Record<MessageIds, string> | Record<MessageIds, MessageFormatElement[]>;
  defaultLocale?: string;
  defaultFormats?: CustomFormats;
  defaultRichTextElements?: Record<string, FormatXMLElementFn<JSXElement>>;
  onError(err: MissingTranslationError | MessageFormatError | MissingDataError | InvalidConfigError | UnsupportedFormatterError | FormatError)?: void;
  onWarn(warning: string)?: void;
}
```

### 语言、格式和消息

用户的当前地块, 以及该应用程序应该提供的内容 . 虽然 `defaultLocale` 财务报告和审定财务报表 `defaultFormats` 用于倒置或开发期间,并代表应用程序的默认值. 注意没有 `defaultMessages`,这是因为每个信件描述符提供了默认的Message.

### 默认本地和默认格式

未翻译信件的默认语言格式( F) `messages`) (中文(简体) ). `defaultLocale` 应该是那个地方 `defaultMessages` 以便判决在一个地方一致。 无 `defaultLocale` 和/或如果设置错误,你可能会遇到这样的情况:句子是英文,但嵌入式日期/时间是西班牙文.

### 默认 Rich 文本元素

富文本格式化函数的标签地图 。 这样做是为了提供一种集中方式来格式化常见标记,例如: `<b>`, (中文(简体) ), `<p>`...或执行代码库中的某些设计系统(例如标准化) `<a>` 或者说 `<button>`(......) (中文(简体) ).

见 [https://github.com/formatjs/formatjs/issues/1752 (中文(简体) )](https://github.com/formatjs/formatjs/issues/1752) 为更多背景.

### 错误

允许用户提供自定义错误处理器. 默认情况下,错误消息会使用 `console.error` 若为 `NODE_ENV` 未设定为 `production`。 。 。 .

### 警告时

允许用户提供自定义警告处理器. 默认情况下,警告信件会使用 `console.warning` 若为 `NODE_ENV` 未设定为 `production`。 。 。 .

## `useIntl()` 钩子

### 格式 日期

```ts
function formatDate(
  value: number | Date,
  options?: Intl.DateTimeFormatOptions & {format?: string}
): string
```

此函数将返回格式化的日期字符串 . 它期望一个 `value` 它可以被解析为一个日期(即, `isFinite(new Date(value))`),并接受 `options` 符合 `DateTimeFormatOptions`。 。 。 .

```ts
intl.formatDate(Date.now(), {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
})

// outputs: 04/01/2023
```

### 格式时间

```ts
function formatTime(
  value: number | Date,
  options?: Intl.DateTimeFormatOptions & {format?: string}
): string
```

此函数将返回格式化的日期字符串,但它与 [`formatDate`](https://npmcn.com/package/%40cookbook/solid-intl/#readme-formatDate) 使用下列默认选项:

```ts
{
    hour: 'numeric',
    minute: 'numeric',
}
```

它期望一个 `value` 它可以被解析为一个日期(即, `isFinite(new Date(value))`),并接受符合 `DateTimeFormatOptions`。 。 。 .

```ts
intl.formatTime(Date.now())
// outputs: "4:03 PM"
```

### 格式化时间

> **布鲁塞尔支持**数字 :
> 
> 这需要 [内通. 相对时间格式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat) 它的浏览器支持有限. 请用我们的 [多边填充](https://formatjs.io/docs/polyfills/intl-relativetimeformat) 如果你打算支持他们.

```ts
type Unit =
  | 'second'
  | 'minute'
  | 'hour'
  | 'day'
  | 'week'
  | 'month'
  | 'quarter'
  | 'year'

type RelativeTimeFormatOptions = {
  numeric?: 'always' | 'auto'
  style?: 'long' | 'short' | 'narrow'
}

function formatRelativeTime(
  value: number,
  unit: Unit,
  options?: Intl.RelativeTimeFormatOptions & {
    format?: string
  }
): string
```

此函数将返回格式化的相对时间字符串( 如“ 1 hour ago” ) 。 它期望一个 `value` 是一个数字, a `unit` 财务报告和审定财务报表 `options` 符合 `Intl.RelativeTimeFormatOptions`。 。 。 .

```ts
intl.formatRelativeTime(0)
// outputs: in 0 seconds
```

```ts
intl.formatRelativeTime(-24, 'hour', {style: 'narrow'})
// outputs: 24 hr ago
```

### 数量

此函数使用 [内通. 数字格式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat) 选项.

```ts
function formatNumber(
  value: number,
  options?: Intl.NumberFormatOptions & {format?: string}
): string
```

此函数将返回格式化的数字字符串 . 它期望一个 `value` 可解析为数字,并接受 `options` 符合 `NumberFormatOptions`。 。 。 .

```ts
intl.formatNumber(1000, {style: 'currency', currency: 'USD'})
// outputs: US$1,000.00
```

**使用单位格式编号**

目前,这是ES2020的一部分 [数字格式](https://tc39.es/ecma402/#numberformat-objects)。 。 。 . 我们提供了 [多边填充](https://formatjs.io/docs/polyfills/intl-numberformat) 这里和 `@formatjs/intl` 类型允许用户在 [被制裁单位](https://formatjs.io/docs/polyfills/intl-numberformat#SupportedUnits)数字 :

```ts
intl.formatNumber(1000, {
  style: 'unit',
  unit: 'kilobyte',
  unitDisplay: 'narrow',
})
// outputs: 1,000kB
```

```ts
intl.formatNumber(1000, {
  unit: 'fahrenheit',
  unitDisplay: 'long',
  style: 'unit',
})
// outputs: 1,000 degrees Fahrenheit
```

### 格式图

```ts
type PluralFormatOptions = {
  type?: 'cardinal' | 'ordinal' = 'cardinal'
}

function formatPlural(
  value: number,
  options?: Intl.PluralFormatOptions
): 'zero' | 'one' | 'two' | 'few' | 'many' | 'other'
```

此函数将返回复数类字符串 : `"zero"`, (中文(简体) ), `"one"`, (中文(简体) ), `"two"`, (中文(简体) ), `"few"`, (中文(简体) ), `"many"`,或 `"other"`。 。 。 . 它期望一个 `value` 可解析为数字,并接受 `options` 符合 `PluralFormatOptions`。 。 。 .

这是一种低级的用途,其产出可提供给 `switch` 语句来选择要显示的特定字符串.

```ts
intl.formatPlural(1)
// outputs: one
```

```ts
intl.formatPlural(3, {style: 'ordinal'})
// outputs: one
```

> **多种语文支助**
> 
> 此函数只应用于只需要支持一种语言的app. 如果您的应用程序支持多种语言,则使用Message格式.

### 格式列表

> **布鲁塞尔支持**
> 
> 这需要 [内通. 列表格式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat) 它的浏览器支持有限。 请用我们的 [多边填充](https://formatjs.io/docs/polyfills/intl-listformat) 如果你打算支持他们.

此函数允许您以 i18n- safe 的方式加入列表 。 例如,当地方是 `en`数字 :

```ts
intl.formatList(['Me', 'myself', 'I'], {type: 'conjunction'})
// outputs: Me, myself and I
```

```ts
intl.formatList(['5 hours', '3 minutes'], {type: 'unit'})
// outputs: 5 hours, 3 minutes
```

### 格式显示Name

> **布鲁塞尔支持**
> 
> 这需要 [内通. 显示名称](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames) 它的浏览器支持有限。 请用我们的 [多边填充](https://formatjs.io/docs/polyfills/intl-displaynames) 如果你打算支持他们.

```ts
type FormatDisplayNameOptions = {
  style?: 'narrow' | 'short' | 'long'
  type?: 'language' | 'region' | 'script' | 'currency'
  fallback?: 'code' | 'none'
}

function formatDisplayName(
  value: string | number | Record<string, unknown>,
  options: FormatDisplayNameOptions
): string | undefined
```

用法示例:

```ts
intl.formatDisplayName('zh-Hans-SG', {type: 'language'})
// outputs: Simplified Chinese (Singapore)
```

```ts
// ISO-15924 four letters script code to localized display name
intl.formatDisplayName('Deva', {type: 'script'})
// outputs: Devanagari
```

```ts
// ISO-4217 currency code to localized display name
intl.formatDisplayName('CNY', {type: 'currency'})
// outputs: Chinese Yuan
```

```ts
// ISO-3166 two letters region code to localized display name
intl.formatDisplayName('UN', {type: 'region'})
// outputs: United Nations
```

### 格式

```ts
type MessageFormatPrimitiveValue = string | number | boolean | null | undefined

function formatMessage(
  descriptor: MessageDescriptor,
  values?: Record<string, MessageFormatPrimitiveValue>
): string

function formatMessage(
  descriptor: MessageDescriptor,
  values?: Record<
    string,
    MessageFormatPrimitiveValue | JSX.Element | FormatXMLElementFn
  >
): string | JSX.Element[]
```

此函数将返回格式化信件字符串 . 它期望一个 `MessageDescriptor` 并接受浅层 `values` 用于在信件中填入占位符的对象.

如果有翻译信件 `id` 已经转交给 `<IntlProvider>` 通过其 `messages` prop 它将被格式化, 否则它会回落到格式化 `defaultMessage`。 。 。 .

> **见**数字 : [信件格式倒置](https://npmcn.com/package/%40cookbook/solid-intl/#readme-message-formatting-fallbacks) 更多细节.

```tsx
function () {
  const messages = defineMessages({
    greeting: {
      id: 'app.greeting',
      defaultMessage: 'Hello, {name}!',
    },
  })

  return intl.formatMessage(messages.greeting, {name: 'Eric'})
  // outputs: Hello, Eric!
}
```

与 `JSX.Element`

```tsx
function () {
  const messages = defineMessages({
    greeting: {
      id: 'app.greeting',
      defaultMessage: 'Hello, {name}!',
    },
  })

  return intl.formatMessage(messages.greeting, {name: <b>Eric</b>})
  // outputs: Hello, <b>Eric</b>!
}
```

有丰富的文本格式

```tsx
function () {
  const messages = defineMessages({
    greeting: {
      id: 'app.greeting',
      defaultMessage: 'Hello, {name}!',
    },
  })

  return intl.formatMessage(messages.greeting, {
    name: 'Eric',
    bold: str => <b>{str}</b>,
  })
  // outputs: Hello, <b>Eric</b>!
}
```

### 定义

```ts
interface MessageDescriptor {
  id?: string
  description?: string | object
  defaultMessage?: string
}

function defineMessages(
  messageDescriptors: Record<string, MessageDescriptor>
): Record<string, MessageDescriptor>

function defineMessage(messageDescriptor: MessageDescriptor): MessageDescriptor
```

这些职能从下列来源再出口: `@formatjs/intl` 软件包,并且只是我们编译 JavaScript 源文件定义的默认信件时使用的 CLI & bail/ TS 插件的钩子 . 此函数仅返回已通过的信件描述符映射对象 .

```ts
import {defineMessages, defineMessage} from '@cookbook/solid-intl'

const messages = defineMessages({
  greeting: {
    id: 'app.home.greeting',
    defaultMessage: 'Hello, {name}!',
  },
})

const msg = defineMessage({
  id: 'single',
  description: 'header',
})
```

* * *

# 信件提取

现在你已经宣布了一些信息, 现在是提取它们的时候了.

```bash
npm i @formatjs/cli
# or
yarn add @formatjs/cli
# or
pnpm add @formatjs/cli
```

### 采掘业

将以下命令添加到您的 `package.json` `scripts`数字 :

```bash
{
  "scripts": {
    "extract": "formatjs extract"
  }
}
```

执行它:

```
npm run extract -- 'src/**/*.ts*' --ignore='**/*.d.ts' --out-file lang/en.json'
```

包含以下消息的文件 :

```tsx
import { useIntl } from '@cookbook/solid-intl'

export function List(props) {
  const intl = useIntl();

  return (
    <section>
      <header>
        {intl.formatMessage({
          id: 'settings.list.header',
          defaultMessage: 'Control Panel',
        })}
      </header>
      <ul>
        <li>
          <button>
            {intl.formatMessage({
              id: 'settings.list.button.delete',
              defaultMessage: 'Delete user {name}',
            }, {
              name: props.name,
            })}
          </button>
        </li>
        <PasswordChange />
      </ul>
    </section>
  )
}
```

运行上述命令将创建一个名为\`lang/en.json'的文件:

```json
{
  "settings.list.header": "Control Panel",
  "settings.list.button.delete": "Delete user {name}"
}
```

* * *

# 基本国际化原则

## 国际化有什么意义?

国际化软件支持全世界人民的语言和文化风俗. 网络遍布世界各地。 国际化网络应用为各地民众提供了良好的用户体验.

本地化软件通过将文本翻译成用户语言,并按照用户的期望格式化数据来适应特定语言和文化. 一个应用程序一般是本地化的,用于一组小地方.

这个 [ECMA-402 JavaScript 国际化规格](https://github.com/tc39/ecma402) 有一个很好的概览.

## 语言和地区

一个"地"指一个地区的语言和文化期望. 它使用定义于 [UTS LDML 数据](https://www.unicode.org/reports/tr35/tr35.html#Identifiers)。 。 。 .

此代码由几个由连字符相隔的部分(-)组成. 第一部分是代表语言的短弦. 第二段,可选部分,是代表区域的短弦. 此外,还可以指定各种扩展和变体.

通常,网络应用是本地化的,只为语言或语言-区域组合. 这类地块代码的例子有:

1.  `en` 联合国
    
2.  `en-US` 在美国讲的英语
    
3.  `en-GB` 在联合王国发言的英语
    
4.  `es-AR` 在阿根廷发言的西班牙语
    
5.  `ar-001` 全世界讲阿拉伯语的人
    
6.  `ar-AE` 在阿拉伯联合酋长国发言的阿拉伯语
    
7.  大多数国际化的应用只支持少量的地产列表.
    

## 翻译字符串

您的应用程序中可能有一些文本, 使用英语或日语等自然语言 。 为了支持其它地块, 您需要翻译这些字符串 .

FormatJS提供了一个机制,可以让你写出应用程序的核心"软件",而不为不同的翻译提供特殊代码. 您的翻译字符串和我们的图书馆中包含了每个地方的考虑.

```ts
const messages = {
  en: {
    GREETING: 'Hello {name}',
  },
  fr: {
    GREETING: 'Bonjour {name}',
  },
}
```

我们使用 [ICU 信件语法](https://unicode-org.github.io/icu/userguide/format_parse/messages) 用于Java、C、PHP和其他各种平台.

* * *

# 信件语法

字符串/信使格式化是Solid Intl的首要特征,它建立在 [ICU 信件格式](https://unicode-org.github.io/icu/userguide/format_parse/messages) 使用 [ICU 信件语法](https://formatjs.io/docs/core-concepts/icu-syntax)。 。 。 . 此消息语法允许简单到复杂的消息被定义,翻译,然后在运行时格式化.

**简单消息 :**

```ts
Hello everyone
```

**简单参数**

你可以使用一个 `{key}` 在信件中设置一个值的参数. 在输入数据中查找密钥,并用其值来插出字符串.

```ts
Hello, {name}
```

**复杂消息 :**

```ts
Hello, {name}, you have {itemCount, plural,
  =0 {no items}
  one {# item}
  other {# items}
}.
```

## 信件描述符

Solid Intl 有一个信件描述器概念,用于定义您的应用程序的默认信件/字符串 . 信件描述符非常有助于提供翻译字符串/消息所需的数据,它们包含以下属性:

-   `id`: 消息的独特而稳定的标识符
-   `description`: 翻译者在UI中如何使用的背景
-   `defaultMessage`: 默认信件(可能是英文)

```ts
interface MessageDescriptor {
  id?: MessageIds;
  description?: string | object;
  defaultMessage?: string | MessageFormatElement[];
}
```

## 信件格式倒置

将API格式化的信息走出一英里,为格式化失败的常见情况提供倒计时; 至少应该总是返回一个非空字符串.

以下是信息格式化倒置算法:

1.  查找和格式化 id 的已翻译信件, 传递给 .
2.  回落到默认Message格式化中 .
3.  回落到 id 源头的翻译消息 .
4.  回落到默认Message源 .
5.  倒向文字信息id.

## 格式化信件参数

数值也可以根据其类型格式化. 你用一个 `{key, type, format}` 说到做到.

论点的要点是:

-   `key` 在输入数据中查找数据的位置
-   `type` 如何解释数值(见下文)
-   `format` 是可选的,是对如何显示这类数据的进一步改进

```bash
I have {numCats, number} cats.
```

### `number` 格式化

该类型用于以对地语敏感的方式格式化数字. 它理解以下可选值: `format` 论点的要素:

```bash
I have {numCats, number} cats.
Almost {pctBlack, number, ::percent} of them are black.
```

内部使用INTl. Number Format API. 您可以定义格式元素的自定义值,这些值将传递到 Intl 。 数字格式构建器.

有时嵌入数字将如何格式化,为翻译提供了很好的上下文. 我们也支持ICU Number Skeletons使用相同的语法:

```bash
The price of this bagel is {num, number, ::sign-always compact-short currency/GBP}
```

你可以多读读这个 [这里](https://unicode-org.github.io/icu/userguide/format_parse/numbers/skeletons.html)。 。 。 .

### `date` 格式化

该类型用于格式化日期的方式对地语敏感. 它理解参数的可选格式元素的以下值:

-   `short` 用于以尽可能短的方式格式化日期
-   `medium` 用于格式化以短文本表示月份的日期
-   `long` 用于格式化以长文本表示月份的日期
-   `full` 用于格式化最详细的日期

```bash
Sale begins {start, date, medium}
```

内部使用 `Intl.DateTimeFormat` API (英语). 您可以定义格式元素的自定义值,这些值将传递给 `Intl.DateTimeFormat` 建筑师.

### `time` 格式化

这种类型用于格式化时间的方式对地语敏感. 它理解参数的可选格式元素的以下值:

-   `short` 用于以小时和分钟格式化时间
-   `medium` 用于以小时、分和秒格式化时间
-   `long` 用于以小时、分、秒和时区格式化时间
-   `full` 和长短一样

```bash
Coupon expires at {expires, time, short}
```

内部使用 `Intl.DateTimeFormat` API (英语). 您可以定义格式元素的自定义值,这些值将传递给 `Intl.DateTimeFormat` 建筑师.

### 支持的日期时间 Skeleton

类似 `number` 类型,我们也支持ICU DateTime骨架. 伊斯兰法院联盟提供 [多种图案](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#date-field-symbol-table) 自定义日期时间格式. 然而,并非所有的都通过ECMA402的Intl API提供. 因此,我们只支持以下模式:

| 符号 | 含义 | 页:1 |
| --- | --- | --- |
| G级 | 大纪元代号 |  |
| 尔 | 年份 |  |
| 联合国 | 年数月数 |  |
| L | 独立月数 |  |
| d. 国家 | 月数 |  |
| 页:1 | 每周天数 |  |
| 电子 | 当地周日 | e. eee 不支持 |
| c. 国家 | 独立当地周日 | c.ccc 不支持 |
| (单位:千美元) | AM/PM标记 |  |
| 页:1 | 小时 \[-1-12\] |  |
| 页:1 | 小时 \[0-23\] |  |
| K级 | 小时 \[0-11\] |  |
| 页:1 | 小时 \[1-24\] |  |
| 页:1 | 分钟 |  |
| 编号 | 第二届 |  |
| 页:1 | 时区 |  |

### `{select}` 格式

这个 `{key, select, matches}` 用于选择输出,将一个值匹配到许多选择中的一个. (这类似于 `switch` 语句可用一些编程语言。 ) 在输入数据中查找密钥 . 对应值被匹配到匹配值之一并返回对应输出. 关键论点必须遵循 [Unicode 模式 语法](https://www.unicode.org/reports/tr31/tr31-9.html#Pattern_Syntax)。 。 。 . 这个 `matches` 是一个空格分隔的列表 `matches`。 。 。 .

匹配的格式匹配 `{output}`。 。 。 . (匹配类似于一些编程语言中发现的开关的大小写 这个 `match` 是一个字面价值. 如果它与值相同 `key` 然后相应 `output` 将被使用.

输出本身就是一种信息,所以它可以是字面字符串,也可以在其内部有较多的参数.

这个 `other` 匹配是特殊的,在没有其他匹配的情况下使用。 (这类似于一些编程语言中发现的开关的默认情况. )

> **危险**
> 
> `other` 需要根据 `icu4j` 执行。 如果 `select` 未使用 `other`。 。 。 .

```bash
{gender, select,
    male {He}
    female {She}
    other {They}
} will respond shortly.
```

以下为巢道辩之例.

```bash
{taxableArea, select,
    yes {An additional {taxRate, number, percent} tax will be collected.}
    other {No taxes apply.}
}
```

### `{plural}` 格式

这个 `{key, plural, matches}` 用于根据当前地块的复数规则选择输出。 和我们家一样 `{select}` 上方的格式,但数值预计为数字并被映射成复数类.

匹配是一个字面价值,并被匹配到其中一个复数类别. 并非所有语言都使用所有的复数类别.

-   `zero`:这一类用于有专为零个项的语法语言. (例子有阿拉伯语和拉脱维亚语。 )
-   `one`:这一类用于具有专门用于某一项的语法语言. 许多语言,但不是全部,都使用这个复数类. (许多受欢迎的亚洲语言,如汉语和日语,不使用这一类
-   `two`:这一类用于具有特有语法的两种语言. (例子有阿拉伯语和威尔士语. )
-   `few`:这一类用于有专门针对少数项的语法语言. 对于一些语言来说,这用于2-4项,用于约3-10项,而其他语言则有更复杂的规则.
-   `many`:这一类用于有专门针对更多项的语法语言. (例子有阿拉伯语、波兰语和俄语。 )
-   `other`: 如果值与其他复数类之一不相匹配,则使用此类. 注意,这个用于"平分",用于语言(如英语)具有简单的"单分"与"平分"两种.
-   `=value`:这用于匹配特定值,无论当前地块的复数类别如何.

> **危险**
> 
> `other` 需要根据 `icu4j` 执行。 如果 `select` 未使用 `other`。 。 。 .

```bash
Cart: {itemCount} {itemCount, plural,
    one {item}
    other {items}
}
```

```bash
You have {itemCount, plural,
    =0 {no items}
    one {1 item}
    other {{itemCount} items}
}.
```

在那个 `output` 比赛中 `#` 特殊令牌可以用作数值的占位符,并将格式化为 `{key, number}`。 。 。 .

### `{selectordinal}` 格式

这个 `{key, selectordinal, matches}` 用于根据当前地块的正数复数规则(第1个、第2个、第3个等)选择输出。 它与上面的{plural}格式非常相近,只是该值被映射为正数复数类.

匹配是一个字面价值,并被匹配到其中一个复数类别. 并非所有语言都使用所有的复数类别.

-   `zero`:这一类用于有专为零个项的语法语言. (例子有阿拉伯语和拉脱维亚语。 )
-   `one`:这一类用于具有专门用于某一项的语法语言. 许多语言,但不是全部,都使用这个复数类. (许多受欢迎的亚洲语言,如汉语和日语,不使用这一类
-   `two`:这一类用于具有特有语法的两种语言. (例子有阿拉伯语和威尔士语. )
-   `few`:这一类用于有专门针对少数项的语法语言. 对于一些语言来说,这用于2-4项,用于约3-10项,而其他语言则有更复杂的规则.
-   `many`:这一类用于有专门针对更多项的语法语言. (例子有阿拉伯语、波兰语和俄语。 )
-   `other`: 如果值与其他复数类之一不相匹配,则使用此类. 注意,这个用于"平分",用于语言(如英语)具有简单的"单分"与"平分"两种.
-   `=value`:这用于匹配特定值,无论当前地块的复数类别如何.

> **危险**
> 
> `other` 需要根据 `icu4j` 执行。 如果 `select` 未使用 `other`。 。 。 .

在产出中 `match`,则 `#` 特殊令牌可以用作数值的占位符,并将格式化为 `{key, number}`。 。 。 .

```bash
It's my cat's {year, selectordinal,
    one {#st}
    two {#nd}
    few {#rd}
    other {#th}
} birthday!
```

### 丰富文本格式

我们也支持使用标记在信件中嵌入丰富的文本格式. 这样可以让开发者尽可能多地嵌入文字,这样句子就不必被分割成块

**注: 这不是 XML/ HTML 标签**

```bash
Our price is <boldThis>{price, number, ::currency/USD precision-integer}</boldThis>
with <link>{pct, number, ::percent} discount</link>
```

### 引用/出逃

ASCII 缩水 `'` (U+0027)可以用来逃避消息中文本部分的语法字符. 单个apostrope在紧接后逃脱了一个语法字符;一对apostrope逃脱了彼此之间包裹的每一个语法字符:

```ts
"This is not an interpolation: '{word}"
//→ "This is not an interpolation: {word}"
"These are not interpolations: '{word1} {word2}'"
//→ "These are not interpolations: {word1} {word2}"
"'<notATag>"
//→ "<notATag>"
"'<notATag>hello</notATag>'"
//→ "<notATag>hello</notATag>"
```

连续两个ASCII层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层层 `%%` 内 `printf` 代表一个 `%`然而,我们建议使用卷曲接力 `’` (U+2019)用于人可读字符串并只使用ASCII apostrope `'` (U+0027)在ICU消息语法中.

```ts
"This '{isn''t}' obvious."
//→ "This {isn't} obvious."
```

## 常见问题

### @cookbook/solid-intl 是什么？

由 React Intl & FormatJS 所启发的 Solid 通用国际化\(i18n\)

### 如何安装 @cookbook/solid-intl？

在项目目录运行 npm install @cookbook/solid-intl，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：solid-js（\>=1\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @cookbook/solid-intl 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @cookbook/solid-intl 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @cookbook/solid-intl 可以商用吗？

@cookbook/solid-intl 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @cookbook/solid-intl 的下载量有多少？

根据 npm 官方下载统计，@cookbook/solid-intl 在 2026/10/11 – 2026/11/09 这 30 天内被下载 6,932 次，日均约 231 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @cookbook/solid-intl 还在维护吗？

最新版本 0\.1\.3 发布于 2025/07/08（1\.3 年前）；至今共发布 4 个版本，其中过去 12 个月发布了 0 个；首次发布于 2023/01/04。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

