# @eturino/key-set 中文文档

规范地址：https://npmcn.com/package/%40eturino/key-set/

版本：6\.0\.0
npm 元数据更新时间：2026-08-31T15:57:34.068Z
中文译文更新时间：2026-11-14T00:08:31.976Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40eturino/key-set
原文对照：https://npmcn.com/package/%40eturino/key-set/?lang=original
项目主页：https://github.com/eturino/ts-key-set
源码仓库：https://github.com/eturino/ts-key-set

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

- 包体积（解压后）：435 kB，118 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=20\.0\.0
- 运行依赖：0 个
- 首次发布：2019-09-07T15:27:02.637Z
- 最新版本发布：2026-08-31T15:57:33.749Z
- 近 30 天下载量：8900（2026-10-14 至 2026-11-12，npm 官方下载统计）
- 已发布版本数：49（近 12 个月 2 个）

## 中文简介

(简体中文) [https://github.com/eturino/ruby key set (英语)](https://github.com/eturino/ruby_key_set)) KeySet 有4个类来代表 All, None, Some, and AllExcuseSome 的概念,最后两个类有排序的 Uniq 密钥列表,全部有相交计算

## 安装

```sh
npm install @eturino/key-set
```

也可以使用：`pnpm add @eturino/key-set`、`yarn add @eturino/key-set`、`bun add @eturino/key-set`

## README

# 密钥集

[![npm version](https://badge.fury.io/js/%40eturino%2Fkey-set.svg)](https://badge.fury.io/js/%40eturino%2Fkey-set) [![CI](https://github.com/eturino/ts-key-set/actions/workflows/ci.yml/badge.svg)](https://github.com/eturino/ts-key-set/actions/workflows/ci.yml)

[Github 重播这里](https://github.com/eturino/ts-key-set)

键盘, 有 4 个 类, 代表 : `All`, (中文(简体) ), `None`, (中文(简体) ), `Some`,以及 `AllExceptSome`最后两个有内部 `Set` 键,所有键都有相交计算.

它还有一个概念: `ComposedKeySet` 包含可采取行动的 KeySets 列表,最后随 `collapseUnion()` 或者说 `collapseIntersect()`

(原件:TypeScript port of [https://github.com/eturino/ruby key set (英语)](https://github.com/eturino/ruby_key_set)(中文(简体) )

## V6 正在中断更改

-   `new ComposedKeySet([])` 现在将空列表正常化为单个 `all()`路边 `composedKeySetFrom([])` 总是这样 之前建筑师保留了空列表, 其中 `contains()` 已回复 `true` (空虚地)而新的 `containsByUnion()` 会回答 `false`。 。 。 .
-   已公布的切入点从 `dist/` 改为 `build/`后,一个 `exports` 地图 : `import` 决定 `build/module/index.js` (ES模块)和 `require` 决定 `build/main/index.js` (共同JS),每个都有自己的 `.d.ts`。 。 。 . `main`, (中文(简体) ), `module` 财务报告和审定财务报表 `types` 仍为年长的捆绑者申报。 按名称导入包不受影响; 深度导入 a `dist/...` 路径不是 `exports` 现在只允许地图 `@eturino/key-set/schemas/*` 财务报告和审定财务报表 `@eturino/key-set/package.json` 作为子路径.
-   ES模块构建不再是一个单一的捆绑文件,它现在在本地节点无害环境管理下运作:相对的规格人员携带它们 `.js` 扩展和 `build/module/package.json` 标记目录为 `type: module`在v6之前 `module` 建筑只能由捆绑者解决.
-   `KEY_SET_TYPES`, (中文(简体) ), `_IS_NODE_ENVIRONMENT` 财务报告和审定财务报表 `isKeyLabelBase` 不再从模块中导出。 没有一个从货包入境点再出口 所以只有深度输入 `src/` 可能已经到达他们.
-   `allExceptSomeForced([])` 现在丢出一个消息名称错误 `allExceptSomeForced`。它曾经说 `someForced`。 。 。 .

V6中也是新的: `ComposedKeySet.containsByUnion()` 编号 : `containsByIntersection()`,并发表 [杰森·斯克马](https://npmcn.com/package/%40eturino/key-set/#readme-json-schema) 用于序列格式.

固定在v6中: `module` 建筑(`dist/index.mjs` 在5.x)中投掷 `Dynamic require of "node:util" is not supported` 当它在类似节点的运行时间 -- -- 无害环境管理输出服务器捆绑 -- -- 中被评价为真正的无害环境管理时,或者通过路径导入该文件。 它没有影响 `require()`, (中文(简体) ), `import` 按软件包名称( 5. x 没有) `exports` 映射, 因此节点解析 `main`),或浏览器捆绑,其中 `process` 未定义和 `node:util` 树枝从未被取走.

## 打破 v5 中的变化

从五年级起 `KeySet` 元素编码为被冻结 `Set` 而不是数组。 它暴露为 `keySet.elements`。 。 。 . 这个 `keySet.keys` 别名已被删除.

作为数组用途的元素列表 `keySet.elementsList`,用于排序版本 `keySet.elementsSorted`。 。 。 .

你可以多吃点 [读取内容部分中的信息](https://npmcn.com/package/%40eturino/key-set/#readme-elements-elementslist-and-elementssorted)。 。 。 .

## 安装

`pnpm add @eturino/key-set`, (中文(简体) ), `yarn add @eturino/key-set` 或者说 `npm install @eturino/key-set`。 。 。 .

## 使用量

我们有四个班:

-   `KeySetAll`: 代表可能键的全部(`𝕌`(中文(简体) )
-   `KeySetNone`: 代表一个空集(`∅`(中文(简体) )
-   `KeySetSome`: 代表一组混凝土(`A ⊂ 𝕌`(中文(简体) )
-   `KeySetAllExceptSome`: 代表一个集合的补充,除给定元素外的所有元素(`A' = {x ∈ 𝕌 | x ∉ A}`(中文(简体) ) _(见 [维基百科中的补充](https://en.wikipedia.org/wiki/Complement_\(set_theory\))(中文(简体) )_

我们可以有一个键盘:

-   `string`编号
-   `number`编号
-   对象为 `key` (单位:千美元)`string` 或者说 `number`和 `label` (单位:千美元)`string`(中文(简体) )

所有元素都必须是同一类的.

### 创建 : `all()`, (中文(简体) ), `none()`, (中文(简体) ), `some([...])`, (中文(简体) ), `allExceptSome([...])`, (中文(简体) ), `allKeySet()`, (中文(简体) ), `noneKeySet()`, (中文(简体) ), `someKeySet([...])`, (中文(简体) ), `allExceptSomeKeySet([...])`, (中文(简体) ), `someForced([...])`, (中文(简体) ), `allExceptSomeForced([...])`

使用构建函数构建您的 keySets

```ts
import { all, allKeySet, none, noneKeySet, some, someKeySet, allExceptSome, allExceptSomeKeySet, someForced, allExceptSomeForced } from "@eturino/key-set";

all(); // => returns a new instance of KeySetAll
allKeySet(); // => returns a new instance of KeySetAll
none(); // => returns a new instance of KeySetNone
noneKeySet(); // => returns a new instance of KeySetNone

some([1, 3, 2, 3]); // returns a new instance of KeySetSome with keys Set<1, 3, 2>
someKeySet([1, 3, 2, 3]); // returns a new instance of KeySetSome with keys Set<1, 3, 2>
some([]); // returns a new instance of KeySetNone
someKeySet([]); // returns a new instance of KeySetNone

allExceptSome([1, 3, 2, 3]); // returns a new instance of KeySetAllExceptSome with keys Set<1, 3, 2>
allExceptSomeKeySet([1, 3, 2, 3]); // returns a new instance of KeySetAllExceptSome with keys Set<1, 3, 2>
allExceptSome([]); // returns a new instance of KeySetAll
allExceptSomeKeySet([]); // returns a new instance of KeySetAll

someForced([1, 3, 2, 3]); // returns a new instance of KeySetSome with keys Set<1, 3, 2>
someForced([]); // throws an InvalidEmptySetError

allExceptSomeForced([1, 3, 2, 3]); // returns a new instance of KeySetAllExceptSome with keys Set<1, 3, 2>
allExceptSomeForced([]); // throws an InvalidEmptySetError
```

### `.elements`, (中文(简体) ), `.elementsList` 财务报告和审定财务报表 `elementsSorted`

-   `.elements` 返回内部 `Set` 用钥匙。 KeySet 从未变异过它,它通过 `Object.freeze()`但请注意,冻结 `Set` 不停止 `.add()`编号 :`.delete()` - 按惯例视其为只读,并使用 `.elementsList` 如果您需要一个可以拥有的阵列.
-   `.elementsList` 返回带有内部集元素的新数组.
-   `.elementsSorted` 返回带有内部集元素的新阵列,排序.

```
some([1, 3, 2, 3]).elements; // => Set<1, 3, 2>
some([1, 3, 2, 3]).elementsList; // => [1, 3, 2]
some([1, 3, 2, 3]).elementsSorted; // => [1, 2, 3]

allExceptSome([1, 3, 2, 3]).elements; // => Set<1, 3, 2>
allExceptSome([1, 3, 2, 3]).elementsList; // => [1, 3, 2]
allExceptSome([1, 3, 2, 3]).elementsSorted; // => [1, 2, 3]
```

### `type`

所有密钥集显示一个 `type` 返回成员的财产 `KeySetTypes` um.

-   `KeySetAll` 返回时 `ALL`
-   `KeySetAllExceptSome` 返回时 `ALL_EXCEPT_SOME`
-   `KeySetNone` 返回时 `NONE`
-   `KeySetSome` 返回时 `SOME`

这些类型也作为字符串 TypeScript 类型的结合而被曝光 `KeySetTypesEnumValues`。 。 。 .

#### `type` 在v1.x对v2.x中

`v2.0` 更改返回的值 `type`,使它们尖叫 SNAKE CASE,这样可以更容易地与GraphQL enums集成.

在v1.x中,数值是 `all`, (中文(简体) ), `allExceptSome`, (中文(简体) ), `none` 财务报告和审定财务报表 `some`。 。 。 .

### `representsXXX()`

所有 KeySet 显示 4 个方法 `representXXX()`。每个班都假冒返回,除了自己的.

-   `representsAll()`数字 : `KeySetAll` 返回时 `true`
-   `representsNone()`数字 : `KeySetNone` 返回时 `true`
-   `representsSome()`数字 : `KeySetSome` 返回时 `true`
-   `representsAllExceptSome()`数字 : `KeySetAllExceptSome` 返回时 `true`

### `clone()`

所有键盘有一个 `clone()` 方法,它将返回代表同一密钥Set的同类新实例.

如果键盘是 `KeySetSome` 或者说 `KeySetAllExceptSome`,它们将有一个带有相同密钥的阵列.

```ts
const newKeySet = keySet.clone();
```

### `isEqual(other)`

所有键盘都有 `isEqual(other)` 如果返回真实的方法 `other` keySet属于同一类,代表同一类的KeySet.

如果键盘是 `KeySetSome` 或者说 `KeySetAllExceptSome`,它们必须有一个有相同密钥的阵列.

### `invert()`

所有键盘都有 `invert()` 方法返回相反类的实例,代表互补的 KeySet. _(见 [维基百科中的补充](https://en.wikipedia.org/wiki/Complement_\(set_theory\))(中文(简体) )_

-   `KeySetAll` ⟷ `KeySetNone`
-   `KeySetSome` ⟷ `KeySetAllExceptSome`

```ts
const complementaryKeySet = keySet.invert();
```

### `remove(other)`

返回新的键盘, 其区别在于此Set - 其他Set `(A - B)`

```ts
const diffKeySet = keySet.remove(other);
```

### `intersect(other)`

返回两个集相交的新密钥组 `(A ∩ B)`,代表两组中的要素

```ts
const diffKeySet = keySet.intersect(other);
```

### `union(other)`

返回两个集结合的新密钥组 `(A U B)`,代表 A 或 B 中的元素

```ts
const unionKeySet = keySet.union(other);
```

### `includes(element)`

别名 `contains(element)`。 。 。 .

如果 KeySet 包含给定元素, 返回布尔定义 .

```ts
const element = "A";

const ksAll: KeySetAll<string> = all<string>();
ksAll.includes(element); // => true
ksAll.contains(element); // => true

const ksNone: KeySetNone<string> = none<string>();
ksNone.includes(element); // => false
ksNone.contains(element); // => false

const ksSome: KeySetSome<string> = some(["A", "B", "C"]);
ksSome.includes(element); // => true
ksSome.contains(element); // => true

const ksSome2: KeySetSome<string> = some(["X", "Y", "Z"]);
ksSome2.includes(element); // => false
ksSome2.contains(element); // => false

const ksAllExceptSome: KeySetAllExceptSome<string> = allExceptSome(["A", "B", "C"]);
ksAllExceptSome.includes(element); // => false
ksAllExceptSome.contains(element); // => false

const ksAllExceptSome2: KeySetAllExceptSome<string> = allExceptSome(["X", "Y", "Z"]);
ksAllExceptSome2.includes(element); // => true
ksAllExceptSome2.contains(element); // => true
```

## 序列化

KeySet 的序列化代表`KeySetSerialized`)是一个普通对象,与 `type` 选择 `elements`。 。 。 .

-   `{ type: "ALL" }`
-   `{ type: "NONE" }`
-   `{ type: "SOME", elements: [1, 2, 3] }`
-   `{ type: "ALL_EXCEPT_SOME", elements: [1, 2, 3] }`

键盘的序列化表达有两种方式

-   `keySet.serialized()`
-   `serializeKeySet(keySet)`

对于KeyLabel集和组成集,有专用功能,类型更窄:

-   `serializeKeyLabelSet(keyLabelSet)`
-   `serializeComposedKeySet(comp)`
-   `serializeComposedKeyLabelSet(comp)`

## 分析

我们可以从序列化的表示中创建一个 KeySet

-   `parseKeySet(serialized)`
-   `parseKeyLabelSet(serialized)`
-   `parseComposedKeySet(serialized)`
-   `parseComposedKeyLabelSet(serialized)`

也可以将实际的键盘传递到 `parseKeySet`,它将返回给定的键盘而不触碰它.

无效的串行值抛出 `InvalidKeySetError`。 。 。 .

## 杰森·斯克马

串行电线格式以JSON Schema(2020-12草案)发布,这样其他语言的客户端就可以在不依赖此库的情况下验证.

同样的两个简介 `v1` 格式, 不变 `$defs` 名字,相互切换需要一个 `$id`数字 :

| 文件 | 描述 | 用它来 |
| --- | --- | --- |
| [`key-set.schema.json`](https://npmcn.com/package/%40eturino/key-set/schemas/v1/key-set.schema.json) | 什麽 `parseKeySet()` **接受** | 验证此库的另一个客户端所写的有效载荷 |
| [`key-set.canonical.schema.json`](https://npmcn.com/package/%40eturino/key-set/schemas/v1/key-set.canonical.schema.json) | 什麽 `serialized()` **发射** | 验证嵌入密钥集的手动编辑文件 |

两者都在 npm 包内运出 `schemas/v1/`,并用 URL 粘贴在不可更改性标签上:

```
https://raw.githubusercontent.com/eturino/ts-key-set/v6.0.0/schemas/v1/key-set.schema.json
https://raw.githubusercontent.com/eturino/ts-key-set/v6.0.0/schemas/v1/key-set.canonical.schema.json
```

在读取Postel定律时 选一个放任性 人类输入文件时选一个 犬科简介禁止 `elements` 打开 `ALL`编号 :`NONE` (允许者容忍一空阵列),禁止未知属性,并要求 `uniqueItems`。3个都不是这个库发出的形状,所以在手动编辑的文件上,每个文件都是一个值一个错误的字典,而不是一个静悄悄地不意味着它是什么样子的值.

Root schema 描述了单个序列化的 KeySet. 其他形状可处理为 `$defs`数字 :

| 指针 | 形状 |
| --- | --- |
| `#/$defs/keySet` | `KeySetSerialized` (根),任意 `Key` 元素 |
| `#/$defs/keyLabelSet` | `KeyLabelSetSerialized`, (中文(简体) ), `IKeyLabel` 只包含元素 |
| `#/$defs/stringKeySet` | 仅字符串元素( 仅定义配置) |
| `#/$defs/composedKeySet` | `ComposedKeySetSerialized` |
| `#/$defs/composedKeyLabelSet` | `ComposedKeyLabelSetSerialized` |
| `#/$defs/composedStringKeySet` | 组成, 只包含字符串元素( 仅包含名称配置) |
| `#/$defs/key` | 单人 `Key` |
| `#/$defs/keyLabel` | 单人 `IKeyLabel` |
| `#/$defs/keySetType` | 页:1 `type` 歧视者 |

如果您的文件格式密钥在普通字符串 ID 上,则指向 `key-set.canonical.schema.json#/$defs/stringKeySet`: 相同的犬科规则,与 `elements` 限于字符串, 所以一个数字或一个 `IKeyLabel` 是一个错误,而不是你从未打算接受的那种有效的密钥集.

这个 `v1` 路径中的版本 **有线格式**,而不是包,它涵盖两个配置:两个 `$id`s,一种格式. 它只有在序列化形状改变现有文档失败的方式时才会改变. 两种方案都与库在每次测试中的实际产出.

更进一步缩小范围 一个图案 一个已知的识别码 `allOf` 您想要自己的简介 `items`。收缩的唯一收缩; 犬科分支保持自己的 `additionalProperties: false`数字 :

```json
{
  "allOf": [
    { "$ref": "https://raw.githubusercontent.com/eturino/ts-key-set/v6.0.0/schemas/v1/key-set.canonical.schema.json" },
    { "properties": { "elements": { "items": { "$ref": "#/$defs/myItemKey" } } } }
  ]
}
```

两种方法都无法表达: **排序** 发射,和 `IKeyLabel` 元素被复制 **按键**,因此两个条目共享 a `key` 标签不相同者也不被排放 - `uniqueItems` 不抓住那对.

两个方案都比运行时分析器更严格:它们验证每个元素都是有效的 `Key`,哪个 `parseKeySet` 不检查,他们拒绝一个不集合的变态 `elements` (单位:千美元)`null`, (中文(简体) ), `0`, (中文(简体) ), `""`, (中文(简体) ), `false`继续 `ALL`编号 :`NONE`,解析器读作缺席 `elements`。未知的属性被解析器和允许配置文件所允许; Cononical 配置文件拒绝这些属性,除非 `IKeyLabel`图书馆会发出它交给的东西.

## 类型预测

有类型的上游被曝光,一个是每个键盘类型,另一个是每个键盘序列化.

-   `isKeySet(x): x is KeySet`
-   `isKeySetAll(x): x is KeySetAll`
-   `isKeySetAllExceptSome(x): x is KeySetAllExceptSome`
-   `isKeySetNone(x): x is KeySetNone`
-   `isKeySetSome(x): x is KeySetSome`
-   `isKeySetSerialized(x): x is KeySetSerialized`
-   `isKeySetAllSerialized(x): x is KeySetAllSerialized`
-   `isKeySetAllExceptSomeSerialized(x): x is KeySetAllExceptSomeSerialized`
-   `isKeySetNoneSerialized(x): x is KeySetNoneSerialized`
-   `isKeySetSomeSerialized(x): x is KeySetSomeSerialized`

我们还有基于元素类型的类型上游,用于序列化和KeySet.

-   `isKeySetOfNumbers`
-   `isKeySetOfStrings`
-   `isKeySetOfNumberKeyLabels`
-   `isKeySetOfStringKeyLabels`
-   `isKeySetSerializedOfNumbers`
-   `isKeySetSerializedOfStrings`
-   `isKeySetSerializedOfNumberKeyLabels`
-   `isKeySetSerializedOfStringKeyLabels`

## UTI 函数

Lib 还导出代码中使用的 2 个函数

-   `setByKeys(listOrSet)`: 返回包含源列表独特元素的新集。 如果给定的元素是 KeyLabel, 则按密钥进行对比 .
-   `sortKeys(iterableOfKeys)`: 排序密钥列表。 如果密钥实际上是 KeyLabel 对象,则按密钥排序. 否则,它们自然被分类。 返回带有排序键的新数组.

## UTI 数组类型

Lib 也导出 2 个 util 阵列类型 `EmptyArray<T>` 财务报告和审定财务报表 `NonEmptyArray<T>`,带有相应的类型上游 `isEmptyArray()`,以及 `isNonEmptyArray()`。 。 。 .

```ts
const lists: Array<NonEmptyArray<any>> = [
  [1], // ok
  [], // error
];

const lists2: Array<EmptyArray<any>> = [
  [], // ok
  [1], // error
];

const a: string[] = [];
isEmptyArray(a); // => true (also sets that a is EmptyArray<string>)
isNonEmptyArray(a); // => false

const b: string[] = ["something"];
isEmptyArray(b); // => false
isNonEmptyArray(b); // => true (also sets that a is NonEmptyArray<string>)
```

## `ComposedKeySet`

KeySets 列表的组成 .

在正常使用的情况下,不需要这样做,可以用 `first.intersect(second)` 或者说 `first.union(second)`。 。 。 .

但是,在另一些情况下,我们必须明确我们相互交织的两组问题.

譬如说. 我们有一份带有标签的项目清单,其中一个项目可以有多个标签. 我们需要用A、B和C等标签过滤那些没有D等标签的物品.

我们不能用 `some(A, B, C).intersect(allExceptSome(D))` 因为那样就只能 `some(A, B, C)`。 。 。 . 所以我们用 `composedKeySetFrom([some(A, B, C), allExceptSome(D)])`。 。 。 .

这样,如果我们有一个搜索引擎 翻译这样的密钥集:

-   `All` => `WHERE 1=1`
-   `None` => `WHERE 1=0`
-   `Some` => `WHERE list.contains(elements)`
-   `AllExceptSome` => `WHERE not list.contains(elements)`

然后,上面的密钥将最终 `WHERE items.labels.contains(A, B, or C) AND NOT items.labels.contains(D)`

对于这个案子,我们得到了 `ComposedKeySet`

```ts
const comp = composedKeySetFrom([some(A, B, C), allExceptSome(D)]);
```

### 正在检查 a 上的元素 `ComposedKeySet`

两个语义,四个方法名:

-   `containsByIntersection(element)`: 只有在 **每个** 列表中的密钥集包含它. `contains(element)` 及其别名 `includes(element)` 是同一个支票.
-   `containsByUnion(element)`: 如果 **任意** 列表中的密钥集包含它.

```ts
const comp = composedKeySetFrom([some([1, 2, 3]), some([1, 4])]);

comp.containsByIntersection(1); // => true  (in both)
comp.containsByIntersection(3); // => false (only in the first)
comp.contains(3); // => false (alias of containsByIntersection)

comp.containsByUnion(3); // => true  (in the first)
comp.containsByUnion(5); // => false (in neither)
```

### 其它 `ComposedKeySet` 方法

-   `collapseUnion()` 编号 : `collapseIntersect()`: 将列表简化为单个键盘.
-   `add(keySet)` 编号 : `addList(keySets)`: 新增了组合的 KeySet, 并添加了指定的组合 .
-   `without(keySet)` 编号 : `withoutList(keySets)`: 一个新的编译KeySet,没有给定的集(与 `isEqual`) (中文(简体) ).
-   `filter(predicate)` 编号 : `map(fn)`:来自幸存成员/被映射成员的新编成的KeySet.
-   `compactUnion()` 编号 : `compactIntersect()`: 将同类型成员合并成一个,通过联合或交叉.
-   `invert()`, (中文(简体) ), `clone()`, (中文(简体) ), `isEqual(other)`, (中文(简体) ), `toString()`,以及 `representsAll()` 编号 : `representsNone()` 编号 : `representsSome()` 编号 : `representsAllExceptSome()`。 。 。 .
-   `list`: KeySets 的基础阵列。 将空列表正常化为单个 `all()`。 。 。 .

### 序列化 a `ComposedKeySet`

序列化为序列化KeySets的内部列表(阵列).

-   `comp.serialized()` 或者说 `serializeComposedKeySet(comp)`,以及 `serializeComposedKeyLabelSet(comp)` 用于键盘集.
-   `parseComposedKeySet(serialized)`,以及 `parseComposedKeyLabelSet(serialized)` 用于键盘集.

我们还有检查类型的职能:

-   `isComposedKeySet(x): x is ComposedKeySet`
-   `isComposedKeyLabelSet(x): x is ComposedKeyLabelSet`
-   `isComposedKeySetSerialized(x): x is ComposedKeySetSerialized`
-   `isComposedKeyLabelSetSerialized(x): x is ComposedKeyLabelSetSerialized`
-   `isComposedKeySetSerializedRepresentsAll(x): x is ComposedKeySetAllSerialized`
-   `isComposedKeySetSerializedRepresentsNone(x): x is ComposedKeySetNoneSerialized`
-   `isComposedKeySetSerializedRepresentsSome(x): x is ComposedKeySetSomeSerialized`
-   `isComposedKeySetSerializedRepresentsAllExceptSome(x): x is ComposedKeySetAllExceptSomeSerialized`

# 扬开版本

两者都是npm未公布的,无法安装. `npm view` 请不要列出它们,所以记录在这里.

-   `5.8.0` 运出已编译的产出 `5.7.0`替换为 `5.8.1`。 。 。 .
-   `5.11.0` 主软件包导出时缺少一些函数 。 已经取代了 `5.11.1`。 。 。 .

## 常见问题

### @eturino/key-set 是什么？

\(简体中文\) https://github\.com/eturino/ruby key set \(英语\)\) KeySet 有4个类来代表 All, None, Some, and AllExcuseSome 的概念,最后两个类有排序的 Uniq 密钥列表,全部有相交计算

### 如何安装 @eturino/key-set？

在项目目录运行 npm install @eturino/key-set，或使用 pnpm add / yarn add / bun add。

### @eturino/key-set 支持 TypeScript 吗？

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

### @eturino/key-set 支持 ESM 还是 CommonJS？

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

### @eturino/key-set 需要什么版本的 Node\.js？

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

### @eturino/key-set 可以商用吗？

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

### @eturino/key-set 的下载量有多少？

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

### @eturino/key-set 还在维护吗？

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

