Skip to content

Commit 1d05fa0

Browse files
committed
feat: 新增 isMobilePhone
1 parent 5d9f971 commit 1d05fa0

2 files changed

Lines changed: 122 additions & 0 deletions

File tree

packages/is/index.test.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
isEmptyObject,
99
isFunction,
1010
isMap,
11+
isMobilePhone,
1112
isNaN,
1213
isNull,
1314
isNullOrUndefined,
@@ -398,3 +399,85 @@ describe('isPlainObject', () => {
398399
expect(isPlainObject(() => {})).toBe(false)
399400
})
400401
})
402+
403+
describe('isMobilePhone', () => {
404+
it('应该识别有效的手机号码', () => {
405+
// 移动号段 - 字符串格式
406+
expect(isMobilePhone('13812345678')).toBe(true)
407+
expect(isMobilePhone('13987654321')).toBe(true)
408+
expect(isMobilePhone('15012345678')).toBe(true)
409+
expect(isMobilePhone('15987654321')).toBe(true)
410+
411+
// 移动号段 - 数字格式
412+
expect(isMobilePhone(13812345678)).toBe(true)
413+
expect(isMobilePhone(13987654321)).toBe(true)
414+
expect(isMobilePhone(15012345678)).toBe(true)
415+
expect(isMobilePhone(15987654321)).toBe(true)
416+
417+
// 联通号段 - 字符串格式
418+
expect(isMobilePhone('13012345678')).toBe(true)
419+
expect(isMobilePhone('13112345678')).toBe(true)
420+
expect(isMobilePhone('18512345678')).toBe(true)
421+
expect(isMobilePhone('18612345678')).toBe(true)
422+
423+
// 联通号段 - 数字格式
424+
expect(isMobilePhone(13012345678)).toBe(true)
425+
expect(isMobilePhone(13112345678)).toBe(true)
426+
expect(isMobilePhone(18512345678)).toBe(true)
427+
expect(isMobilePhone(18612345678)).toBe(true)
428+
429+
// 电信号段 - 字符串格式
430+
expect(isMobilePhone('18012345678')).toBe(true)
431+
expect(isMobilePhone('18112345678')).toBe(true)
432+
expect(isMobilePhone('19012345678')).toBe(true)
433+
expect(isMobilePhone('19912345678')).toBe(true)
434+
435+
// 电信号段 - 数字格式
436+
expect(isMobilePhone(18012345678)).toBe(true)
437+
expect(isMobilePhone(18112345678)).toBe(true)
438+
expect(isMobilePhone(19012345678)).toBe(true)
439+
expect(isMobilePhone(19912345678)).toBe(true)
440+
})
441+
442+
it('应该拒绝无效的手机号码', () => {
443+
// 长度不对 - 字符串格式
444+
expect(isMobilePhone('1381234567')).toBe(false) // 10位
445+
expect(isMobilePhone('138123456789')).toBe(false) // 12位
446+
447+
// 长度不对 - 数字格式
448+
expect(isMobilePhone(1381234567)).toBe(false) // 10位
449+
expect(isMobilePhone(138123456789)).toBe(false) // 12位
450+
451+
// 不是以1开头
452+
expect(isMobilePhone('23812345678')).toBe(false)
453+
expect(isMobilePhone('01812345678')).toBe(false)
454+
expect(isMobilePhone(23812345678)).toBe(false)
455+
456+
// 第二位不是3-9
457+
expect(isMobilePhone('10812345678')).toBe(false)
458+
expect(isMobilePhone('11812345678')).toBe(false)
459+
expect(isMobilePhone('12812345678')).toBe(false)
460+
expect(isMobilePhone(10812345678)).toBe(false)
461+
expect(isMobilePhone(11812345678)).toBe(false)
462+
expect(isMobilePhone(12812345678)).toBe(false)
463+
464+
// 包含非数字字符(只对字符串有效)
465+
expect(isMobilePhone('138-1234-5678')).toBe(false)
466+
expect(isMobilePhone('138 1234 5678')).toBe(false)
467+
expect(isMobilePhone('138a1234567')).toBe(false)
468+
469+
// 非字符串非数字类型
470+
expect(isMobilePhone(null)).toBe(false)
471+
expect(isMobilePhone(undefined)).toBe(false)
472+
expect(isMobilePhone({})).toBe(false)
473+
expect(isMobilePhone([])).toBe(false)
474+
expect(isMobilePhone(true)).toBe(false)
475+
476+
// 空字符串
477+
expect(isMobilePhone('')).toBe(false)
478+
479+
// 特殊数字情况
480+
expect(isMobilePhone(Number.NaN)).toBe(false)
481+
expect(isMobilePhone(Infinity)).toBe(false)
482+
})
483+
})

packages/is/index.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,3 +425,42 @@ export function isPlainObject(value: unknown): value is Record<string, any> {
425425
const proto = Object.getPrototypeOf(value)
426426
return proto === Object.prototype || proto === null
427427
}
428+
429+
/**
430+
* 检查值是否为有效的手机号码
431+
* @param val 要检查的值
432+
* @returns 如果是有效的手机号码则返回 true,否则返回 false
433+
* @group Is
434+
* @example
435+
* ```ts
436+
* isMobilePhone('13812345678') // true
437+
* isMobilePhone(13812345678) // true
438+
* isMobilePhone('15987654321') // true
439+
* isMobilePhone(15987654321) // true
440+
* isMobilePhone('18600000000') // true
441+
* isMobilePhone(18600000000) // true
442+
* isMobilePhone('12345678901') // false(不是有效号段)
443+
* isMobilePhone(12345678901) // false(不是有效号段)
444+
* isMobilePhone('1381234567') // false(长度不对)
445+
* isMobilePhone(1381234567) // false(长度不对)
446+
* isMobilePhone('138123456789') // false(长度不对)
447+
* isMobilePhone(138123456789) // false(长度不对)
448+
* isMobilePhone('') // false
449+
* isMobilePhone(null) // false
450+
* ```
451+
*/
452+
export function isMobilePhone(val: unknown): boolean {
453+
// 如果既不是字符串也不是数字,直接返回 false
454+
if (!isString(val) && !isNumber(val)) {
455+
return false
456+
}
457+
458+
// 转换为字符串进行验证
459+
const phoneStr = String(val)
460+
461+
// 中国大陆手机号码正则表达式
462+
// 11位数字,以1开头,第二位是3-9的数字
463+
const mobileRegex = /^1[3-9]\d{9}$/
464+
465+
return mobileRegex.test(phoneStr)
466+
}

0 commit comments

Comments
 (0)