TypeScript实战:轻松实现数字序号转中文大写数字
在前端开发中,我们经常会遇到【将数字序号转换为中文大写数字】的需求——比如表单步骤条显示“第一步”而非“第1步”、文章章节标题用“三”代替 “3”等。今天就带大家拆解这个常见需求的实现思路,用TypeScript写出简洁又安全的转换函数。
一、需求明确:我们要解决什么问题?
首先要明确核心诉求:输入一个数字序号(如0、1、……9),输出对应的中文大写数字(如一、二、十)。
需要注意两个细节:
- 序号的起始值:多数场景下序号从0开始(如数组索引),此时0对应一,1对应二;若序号从1开始,则1对应一,需根据业务调整映射关系。
- 边界处理:当输入超出预设范围的数字(如仅支持0-9,却输入11),需返回合理结果(空字符串、默认值或抛错),避免程序异常。
二、常见实现方案:从简单到灵活
方案一:对象映射
这是最直观的实现方式,适合固定范围的序号转换(如仅支持0-9的序号),代码如下:
const numberToUpperCase = (num: number): string => {// 1. 定义数字与大写汉字的映射关系const numberMap: { [key: number]: string } = {0: '一', 1: '二', 2: '三', 3: '四', 4: '五',5: '六', 6: '七', 7: '八', 8: '九'};// 2. 检查输入是否在映射范围内,存在则返回对应值,否则返回空字符串return numberMap.hasOwnProperty(num) ? numberMap[num] : '';
};
代码拆解:
- 类型安全:用{[key: number]: string}明确numberMap是“数字键—字符串值”的对象,避免键类型混乱。
- 映射逻辑:直接通过键值对绑定序号与大写汉字,查找效率(O(1)),适合固定范围场景。
- 边界处理:用hasOwnProperty检查输入是否为有效键,避免访问undefined;超出范围返回空字符串,方便业务层做后续处理(如显示"–")。
方案二:数组映射(更适合连续序号)
若序号是连续的整数范围(如0-9),用数组映射比对象更简洁——数组索引即序号,元素即对应大写汉字:
const indexToChinese = (num: number): string => {const chineseList = [ '一', '二', '三', '四', '五', '六', '七', '八', '九'];// 边界处理:超出范围抛错,更适合严格场景if (num < 0 || num >= chineseList.length) {throw new Error(`当前仅支持 0-${chineseList.length - 1} 的序号,输入值:${num}`);}return chineseList[num];
};
方案对比:
特性 | 对象映射 | 数组映射 |
---|---|---|
适用场景 | 非连续序号 | 连续序号 |
查找效率 | O(1) | O(1) |
边界处理 | 返回空字符串 | 抛错(严格,适合强校验) |
扩展性 | 需手动添加键值对 | 只需在数组尾部追加元素 |
方案三:进阶优化:支持更大范围的数字
以上两种方案仅支持固定范围,若需要转换20以上甚至百位、千位的数字,硬编码映射表就不现实了,需用算法动态生成:
const numberToChineseAdvanced = (num: number): string => {const digits = ['零', '一','二','三','四','五','六','七','八','九'];// 位数映射(十、百、千)const units = ['', '十','百','千'];// 边界校验if(num < 1 || num > 9999) {return '暂支持1-9999的数字转换';}// 数字转字符串, 按位处理const numStr = num.toString();let result = '';for(let i = 0; i < numStr.length; i++) {const digit = parseInt(numStr[i], 10);// 计算当前位数const position = numStr.length - 1 - i;if(digit !== 0) {// 非零result += digits[digit] +units[position];} else if(i < numStr.length - 1 && parseInt(numStr[i+1], 10) !== 0) {// 零的处理result += digits[digit]}}// 特殊处理 "十"开头 如(10 =》 “十”,而非“一十”;11=》“十一”)if(numStr.length === 2 && numStr[0] === '1') {result = result.slice(1);}return result;
}
三、总结
数字序号转中文大写数字的实现,核心是【根据需求选择合适的映射/算法方案】:
- 简单固定范围(如0-9):用对象/数组映射,代码简洁、性能高
- 大范围数字(如1-9999):用算法动态生成,避免硬编码
- 边界处理:根据业务选择“返回空字符串”或“抛错”,保证程序稳定性
- TypeScript优势:通过类型注解明确参数/返回值类型,减少类型错误