Skip to content

ExploringTheCodeWorld/relationship-ts

Repository files navigation

Relationship TypeScript

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 KB 78.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)

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

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 KB 78.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!

About

中国亲戚关系计算器

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors