# @coderspirit/nominal 中文文档

规范地址：https://npmcn.com/package/%40coderspirit/nominal/

版本：4\.1\.1
npm 元数据更新时间：2024-08-15T13:52:37.485Z
中文译文更新时间：2026-11-10T07:46:10.943Z
软件包许可：MIT

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

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

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

- 包体积（解压后）：27.8 kB，9 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=18\.0\.0
- 运行依赖：1 个
- 首次发布：2021-03-28T21:57:38.720Z
- 最新版本发布：2024-08-12T11:03:02.077Z
- 近 30 天下载量：47292（2026-10-10 至 2026-11-08，npm 官方下载统计）
- 已发布版本数：23（近 12 个月 0 个）

## 中文简介

用于您的工程的强大的名义类型

## 安装

```sh
npm install @coderspirit/nominal
```

也可以使用：`pnpm add @coderspirit/nominal`、`yarn add @coderspirit/nominal`、`bun add @coderspirit/nominal`

## README

# @coderspirit/名义上

[![NPM version](https://img.shields.io/npm/v/@coderspirit/nominal.svg?style=flat)](https://www.npmjs.com/package/@coderspirit/nominal) [![TypeScript](https://badgen.net/npm/types/@coderspirit/nominal)](http://www.typescriptlang.org/) [![License](https://badgen.net/npm/license/@coderspirit/nominal)](https://opensource.org/licenses/MIT) [![npm downloads](https://img.shields.io/npm/dm/@coderspirit/nominal.svg?style=flat)](https://www.npmjs.com/package/@coderspirit/nominal) [![Known Vulnerabilities](https://snyk.io//test/github/Coder-Spirit/nominal/badge.svg?targetFile=@coderspirit/nominal/package.json)](https://snyk.io//test/github/Coder-Spirit/nominal?targetFile=@coderspirit/nominal/package.json) [![Security Score](https://snyk-widget.herokuapp.com/badge/npm/@coderspirit%2Fnominal/badge.svg)](https://snyk.io/advisor/npm-package/@coderspirit/nominal)

`Nominal` 提供有力的工具包 [名义打字](https://en.wikipedia.org/wiki/Nominal_type_system) 打开 [字体](https://www.typescriptlang.org/) 零运行时间高空.

它提供三种名义类型:

-   **品牌:** 品牌基本符合传统的名义打字概念. 品牌值只能属于一个 _品牌_,仅标出变量 接受相同数值 _品牌_。 。 。 .
-   **火焰 :** _火焰_ 和品牌类似,只有一个区别: 有口味 变量还接受相同无品牌/无习惯值 _基准类型_。 。 。 . 它们在处理"刚性"代码生成器或其他情况时非常有用 在那里,我们将被迫 写出吨的绘图 只是满足类型 检查器.
-   **属性 :** 说出逻辑和 数学属性,但也执行一种弱形式的 [依赖类型](https://en.wikipedia.org/wiki/Dependent_type)。 。 。 .

虽然每种类型只能有一个 _品牌_ 或一个 _风味_我们很容易 组合 _品牌_ 或者说 _口味_ 与 _属性_。 。 。 .

## 安装指令

### 节点

```
# With NPM
npm install --save-dev @coderspirit/nominal

# Or with PNPM
pnpm add --save-dev @coderspirit/nominal

# Or with Yarn:
yarn add --dev @coderspirit/nominal
```

> \[TIP\] 请注意, 如果您正在开发一个应用程序, 安装是好的 `@coderspirit/nominal` 作为发展依赖,但可能有必要 以正常或对等的依赖方式安装,以防您正在开发您的 拥有基于它的图书馆.

## 品牌

```typescript
import { WithBrand } from '@coderspirit/nominal'

type Email = WithBrand<string, 'Email'>
type Username = WithBrand<string, 'Username'>

const email: Email = 'admin@acme.com' as Email // Ok
const user: Username = 'admin' as Username // Ok
const text: string = email // OK
const anotherText: string = user // Ok

const eMail: Email = 'admin@acme.com' // Error, as we don't have a cast here
const mail: Email = user // Error, as the brands don't match
```

#### **咨询**

-   虽然我们在这里表演"静态的铸造",但只有在以下情况下才能这样做:
    -   值为字面( 如示例)
    -   在鉴定、消毒和/或反腐败层面.
-   一种防止其他开发者“伪造”类型的方法是使用 符号而不是字符串作为属性键或属性值定义时 新的名义类型.

## 火焰

```typescript
import { WithFlavor } from '@coderspirit/nominal'

type Email = WithFlavor<string, 'Email'>
type Username = WithFlavor<string, 'Username'>

const email: Email = 'admin@acme.com' as Email // Ok
const user: Username = 'admin' as Username // Ok
const text: string = email // OK
const anotherText: string = user // Ok

const eMail: Email = 'admin@acme.com' // Ok, flavors are more flexible than brands
const mail: Email = user // Error, as the flavors don't match
```

#### **咨询**

-   虽然我们在这里表演"静态的铸造",但只有在以下情况下才能这样做:
    -   值为字面( 如示例)
    -   在鉴定、消毒和/或反腐败层面.
-   一种防止其他开发者“伪造”类型的方法是使用 符号而不是字符串作为属性键或属性值定义时 新的名义类型.

### 更快的品牌和口味

类型 `WithBrand` 财务报告和审定财务报表 `WithFlavor`虽然目的很简单, 隐藏一个非常复杂的机器 存在的唯一目的就是维护 与其他更复杂的类型完全兼容,例如 `WithProperty`。 。 。 .

多数时候我们不需要依赖 如此复杂的机制,因为我们 应用 `WithBrandh` 财务报告和审定财务报表 `WithFlavor` 基本类型。 所以,如果我们想尽量减少 我们的汇编类型,我们可以选择一个更简单、更快的执行:

```typescript
import {
  FastBrand,
  FastFlavor,
  WithBrand,
  WithFlavor
} from '@coderspirit/nominal'

// These two types are 100% equivalent, but the second one takes less time to be
// compiled. Notice that they are 100% equivalent only because they were applied
// to "basic" types (without other associated metadata, like `WithProperty`).
type SlowEmailType = WithBrand<string, 'Email'>
type FastEmailType = FastBrand<string, 'Email'>

// Same for flavors.
type SlowPhoneNumberType = WithFlavor<string, 'PhoneNumber'>
type FastPhoneNumberType = FastFlavor<string, 'PhoneNumber'>
```

## 属性

### 导言

要定义带有属性的新类型,我们可以做到:

```typescript
import { WithProperty } from '@coderspirit/nominal'
type Even = WithProperty<number, 'Parity', 'Even'>
const myEven: Even = 42 as Even
```

如果我们想将这些属性用作简单的标记, 我们可以省略属性值, 它会默认 `true`,虽然它不太灵活:

```typescript
import { WithProperty } from '@coderspirit/nominal'
type Positive = WithProperty<number, 'Positive'>
const myPositive: Positive = 1 as Positive
```

#### **有意思,你这混蛋 _属性_**

-   `WithProperty` 具有添加剂、共通性和一能性.
-   前一点意味着我们不必担心 我们不会因为这个而出现打字不一致的情况.

`WithProperty` 两者完全兼容:

-   "经典" `&` 类型运算符 :
    
    ```typescript
    type PositiveEven = WithProperty<number, 'Parity', 'Even'> & WithProperty<number, 'Positive'>
    ```
    
-   巢穴类型 :
    
    ```typescript
    type PositiveEven = WithProperty<WithProperty<number, 'Positive'>, 'Parity', 'Even'>
    ```
    

#### **咨询**

-   虽然我们在这里表演"静态的铸造",但只有在以下情况下才能这样做:
    -   值为字面( 如示例)
    -   在鉴定、消毒和/或反腐败层面.
-   一种防止其他开发者“伪造”类型的方法是使用 符号而不是字符串作为属性键或属性值定义时 新的名义类型.

### 疯狂的严格

如果我们愿意,我们甚至可以定义"财产类型",以确保我们不设定 无效值 :

```typescript
import { PropertyTypeDefinition, WithStrictProperty } from '@coderspirit/nominal'
type Parity = PropertyTypeDefinition<'Parity', 'Even' | 'Odd'>

// == WithProperty<number, 'Parity', 'Even'>
type Even = WithStrictProperty<number, Parity, 'Even'>

// == never
type Wrong = WithStrictProperty<number, Parity, 'Seven'>
```

### 高级使用型号( 依赖性类型)

#### **属性可以跨函数边界保存**

当我们需要验证许多属性时,这个特性可能非常有用 同样的价值,我们不想失去 这条路上的信息与价值 从一个函数传递到另一个函数.

```typescript
function throwIfNotEven<T extends number>(v: T): WithProperty<T, 'Parity', 'Even'> {
  if (v % 2 == 1) throw new Error('Not Even!')
  return v as WithProperty<T, 'Even'>
}

function throwIfNotPositive<T extends number>(v: T): WithProperty<T, 'Sign', 'Positive'> {
  if (v <= 0) throw new Error('Not positive!')
  return v as WithProperty<T, 'Positive'>
}

const v1 = 42

// typeof v2 === WithProperty<number, 'Parity', 'Even'>
const v2 = throwIfNotEven(v1)

// typeof v3 extends WithProperty<number, 'Parity', 'Even'>
// typeof v3 extends WithProperty<number, 'Sign', 'Positive'>
const v3 = throwIfNotPositive(v2)
```

#### 选择要跨越函数界限保存哪些属性

在前一个例子中,我们可以增加许多属性,因为我们只是 对价值做出断言。 当我们改变过去的价值观时,我们必须 注意我们保存的东西.

作为我们在这里所说的话的一个简单例子,我们可以看到增加 `1` 改为 数字变量会翻转它的等分, 因此在这种情况下,我们不想保持 返回值上的财产.

```typescript
type Even<N extends number = number> = WithProperty<N, 'Parity', 'Even'>
type Odd<N extends number = number> = WithProperty<N, 'Parity', 'Odd'>

// 1. 'Parity' is overwritten (when available)
// 2. 'Sign' is kept only if it's positive
// 3. We discard all other properties because they might stop being true
type PlusOneResult<N> = KeepProperties<
  N extends Even
    ? KeepPropertyIfValueMatches<Odd<N>, 'Sign', 'Positive'>
    : N extends Odd
    ? KeepPropertyIfValueMatches<Even<N>, 'Sign', 'Positive'>
    : KeepPropertyIfValueMatches<N, 'Sign', 'Positive'>,
  'Sign' | 'Parity'
>

function plusOne<N extends number>(v: N): PlusOneResult<N> {
  return v + 1 as PlusOneResult<N>
}
```

## 常见问题

### @coderspirit/nominal 是什么？

用于您的工程的强大的名义类型

### 如何安装 @coderspirit/nominal？

在项目目录运行 npm install @coderspirit/nominal，或使用 pnpm add / yarn add / bun add。

### @coderspirit/nominal 支持 TypeScript 吗？

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

### @coderspirit/nominal 支持 ESM 还是 CommonJS？

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

### @coderspirit/nominal 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=18\.0\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @coderspirit/nominal 可以商用吗？

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

### @coderspirit/nominal 的下载量有多少？

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

### @coderspirit/nominal 还在维护吗？

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

