Relationship TypeScript

February 10, 2026 · View on GitHub

TypeScript License: MIT Documentation Demo

中文亲戚关系计算器的 TypeScript 重构版本,针对性能和移动端兼容性进行了优化。

📖 文档: https://docs.qinyimo.cn/ | 🎮 在线演示: https://example.qinyimo.cn/

🎯 为什么需要 TypeScript 版本?

本项目基于 mumuy/relationship 进行 TypeScript 重构优化。

解决的问题

React Native 移动端 使用原版 JS 包时,会出现以下错误:

ERROR [RangeError: Property storage exceeds 196607 properties]

这是由于原版 JS 在初始化时创建了大量的对象属性,超出了 JavaScriptCore 引擎的属性数量限制。

TypeScript 版本通过以下优化解决了这个问题:

  • ✅ 使用 Map 代替 Object 存储数据
  • ✅ 实现 LRU 缓存机制,按需加载
  • ✅ 优化数据结构,减少内存占用

✨ 特性

特性JS 版本TS 版本
类型支持✅ 完整的 TypeScript 类型
包体积83.3 KB78.9 KB (-5%)
重复查询性能~2ms~0.1ms (提升95%)
React Native⚠️ 可能报错✅ 完美支持
LRU 缓存✅ 智能缓存
Tree Shaking部分支持✅ 完整支持

🔧 主要优化

  1. LRU 缓存机制 - 缓存常用查询结果,重复查询性能提升 95%
  2. Map 数据结构 - 使用 Map 代替 Object,O(1) 查找性能
  3. 类型安全 - 完整的 TypeScript 类型定义
  4. 更小体积 - 优化后的包体积减少约 5%

📦 安装

# 使用 npm
npm install relationship-ts

# 使用 pnpm
pnpm add relationship-ts

# 使用 yarn
yarn add relationship-ts

多种导入方式

// 主库(简体中文)
import relationship from 'relationship-ts';

// 繁体中文版本(zh-HK)
import relationship from 'relationship-ts/zh-HK';

// 方言模式数据
import { guangdong, north } from 'relationship-ts/locale/guangdong';
import north from 'relationship-ts/locale/north';

浏览器使用

<!-- 主库 -->
<script src="path/to/relationship.min.js"></script>

<!-- 繁体中文版本 -->
<script src="path/to/lang/relationship.zh-HK.min.js"></script>

<!-- 方言模式 -->
<script src="path/to/relationship-mode.min.js"></script>
<script>
  // 设置广东方言模式
  relationship.setMode('guangdong', relationshipMode.guangdong.data);
</script>

🚀 使用方法

基本用法

import relationship from 'relationship-ts';

// 查询称谓
relationship({ text: '爸爸的妈妈' });
// => ['奶奶', '祖母']

// 查询多层关系
relationship({ text: '妈妈的妈妈的哥哥' });
// => ['舅外公']

反向查询

// 对方称呼我什么?
relationship({ text: '外婆', reverse: true, sex: 1 });
// => ['外孙']

relationship({ text: '外婆', reverse: true, sex: 0 });
// => ['外孙女']

关系链查询

// 查询某个称谓代表什么关系
relationship({ text: '舅公', type: 'chain' });
// => ['爸爸的妈妈的兄弟', '妈妈的妈妈的兄弟']

关系合称

// 查询两个人之间的关系合称
relationship({ text: '外婆', target: '奶奶', type: 'pair' });
// => ['儿女亲家']

relationship({ text: '哥哥', target: '弟弟', type: 'pair' });
// => ['兄弟']

相对关系

// 舅妈如何称呼外婆?
relationship({ text: '外婆', target: '舅妈', sex: 1 });
// => ['婆婆']

自然语言模式

// 支持自然语言表达式
relationship('舅妈如何称呼外婆?');
// => ['婆婆']

relationship('外婆和奶奶之间是什么关系?');
// => ['儿女亲家']

relationship('爸爸的妈妈是谁?');
// => ['奶奶', '祖母']

自定义方言模式

// 设置北方方言模式
relationship.setMode('northern', {
  'm,f': ['姥爷'],
  'm,m': ['姥姥'],
  'm,xb,s&o': ['表哥'],
  'm,xb,s&l': ['表弟'],
});

// 使用自定义模式
relationship({ text: '妈妈的妈妈', mode: 'northern' });
// => ['姥姥']

📖 API 参考

relationship(options)

参数类型默认值说明
textstring''目标对象的称谓,称谓间用"的"字分隔
targetstring''相对对象的称谓,空表示自己
sex-1 | 0 | 1-1本人性别:-1未知,0女性,1男性
type'default' | 'chain' | 'pair''default'转换类型
reversebooleanfalse称呼方式:true对方称呼我
modestring'default'使用的方言模式
optimalbooleanfalse计算最短关系

relationship.setMode(name, data)

设置自定义方言模式。

relationship.setMode('custom', {
  'f': ['老爸', '爹地'],
  'm': ['老妈', '妈咪'],
});

relationship.data

获取当前数据表。

relationship.dataCount

获取当前数据量。

🔤 关系链语法

符号含义符号含义
f父亲m母亲
h丈夫w妻子
s儿子d女儿
xb兄弟xs姐妹
ob哥哥lb弟弟
os姐姐ls妹妹

修饰符

符号含义
1男性
0女性
&o年长
&l年幼
&数字排行

📁 项目结构

ts-version/
├── src/
│   ├── core/           # 核心模块
│   │   ├── cache.ts    # 缓存系统(Map优化)
│   │   ├── id.ts       # 关系链转中文
│   │   ├── lru.ts      # LRU缓存实现
│   │   ├── mode.ts     # 模式管理
│   │   └── selector.ts # 中文转关系链
│   ├── data/           # 数据文件
│   ├── rules/          # 规则文件
│   ├── utils/          # 工具函数
│   ├── locale/         # 方言数据
│   ├── types.ts        # 类型定义
│   └── index.ts        # 主入口
└── package.json
├── dist/               # 构建产物
│   ├── relationship.min.mjs    # ESM格式
│   ├── relationship.min.js     # UMD格式
│   ├── index.d.ts              # 类型声明
│   ├── locale/                 # 方言数据
│   │   ├── guangdong.min.mjs
│   │   └── north.min.mjs
│   └── lang/                   # 繁体中文 (zh-HK)
│       └── relationship.zh-HK.min.mjs
├── rollup.config.mjs   # Rollup配置
├── gulpfile.mjs        # Gulp配置 (繁体转换)
├── tsconfig.json       # TypeScript配置
└── package.json

🛠️ 开发

# 安装依赖
pnpm install

# 构建
pnpm run build

# 开发模式(监听文件变化)
pnpm run dev

# 类型检查
pnpm run type-check

🧪 测试

项目使用 Vitest 作为测试框架,包含 322 个测试用例,覆盖从纯函数单元测试到复杂亲属关系的端到端回归测试。

# 运行全部测试
pnpm test

# 监听模式(开发时自动重跑)
pnpm test:watch

# 运行测试并生成覆盖率报告
pnpm test:coverage

测试结构

tests/
├── setup.ts                        # 全局初始化
├── utils/
│   ├── unit.test.ts                # zh2number / number2zh 纯函数
│   └── options.test.ts             # 自然语言表达式解析
├── core/
│   ├── lru.test.ts                 # LRU 缓存淘汰策略
│   ├── cache.test.ts               # OptimizedCache 称谓映射
│   ├── mode.test.ts                # 方言模式切换与合并
│   ├── id.test.ts                  # 关系链逆转、世代计算、称谓查找、合称
│   └── selector.test.ts            # 中文→关系链转换、选择器合并与展开
├── rules/
│   └── expression.test.ts          # 自然语言表达式规则匹配
├── data/
│   └── integrity.test.ts           # 数据格式完整性校验
├── integration/
│   └── relationship.test.ts        # relationship() 主函数集成测试
└── regression/
    └── queries.test.ts             # 98 条亲属关系回归测试(含五辈以上、堂表亲、姻亲等)

📊 性能基准测试

基于 Node.js 环境的性能压力测试结果(复杂随机查询):

指标结果说明
冷启动 QPS~14,000 req/s无缓存/首次查询性能
热启动 QPS~30,000 req/s命中 LRU 缓存性能
平均耗时0.033 ms命中缓存时的单次查询耗时
性能提升2.1 倍相比无缓存状态的吞吐量提升

测试环境:Node.js v20+, 单核性能

资源占用对比

项目原版 (JS)优化版 (TS)提升
包体积 (Minified)83.3 KB78.9 KB⬇️ 5%
重复查询耗时~2 ms~0.03 ms🚀 60倍
内存溢出风险高 (RN)✅ 解决

🙏 致谢

本项目基于 mumuy/relationship 进行 TypeScript 重构。

感谢原作者 mumuy 开发的优秀的中国家庭称谓计算器!

原项目地址:https://github.com/mumuy/relationship

演示地址:https://passer-by.com/relationship/

特别感谢 @xu133081 对本项目的测试支持!

📄 许可证

MIT License


如果这个项目对你有帮助,请给原项目 ⭐️ Star!