From d2ddba367b7409de7d14e6a033e7dbcb380c0e58 Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Tue, 14 Apr 2026 07:13:50 +0800 Subject: [PATCH 1/4] fix: refines number type check --- packages/hooks/src/useCountDown/index.ts | 14 ++++---- .../hooks/src/useVirtualList/demo/demo1.tsx | 17 +++++---- .../hooks/src/utils/__tests__/index.spec.ts | 35 +++++++++++-------- packages/hooks/src/utils/index.ts | 16 +++++---- 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/packages/hooks/src/useCountDown/index.ts b/packages/hooks/src/useCountDown/index.ts index bcb8866b76..bc5516edcb 100644 --- a/packages/hooks/src/useCountDown/index.ts +++ b/packages/hooks/src/useCountDown/index.ts @@ -1,7 +1,7 @@ -import dayjs from 'dayjs'; -import { useEffect, useMemo, useState } from 'react'; -import useLatest from '../useLatest'; -import { isNumber } from '../utils/index'; +import dayjs from "dayjs"; +import { useEffect, useMemo, useState } from "react"; +import useLatest from "../useLatest"; +import { isNumber } from "../utils"; export type TDate = dayjs.ConfigType; @@ -43,10 +43,12 @@ const useCountdown = (options: Options = {}) => { const { leftTime, targetDate, interval = 1000, onEnd } = options || {}; const memoLeftTime = useMemo(() => { - return isNumber(leftTime) && leftTime > 0 ? Date.now() + leftTime : undefined; + return isNumber(leftTime) && leftTime > 0 + ? Date.now() + leftTime + : undefined; }, [leftTime]); - const target = 'leftTime' in options ? memoLeftTime : targetDate; + const target = "leftTime" in options ? memoLeftTime : targetDate; const [timeLeft, setTimeLeft] = useState(() => calcLeft(target)); diff --git a/packages/hooks/src/useVirtualList/demo/demo1.tsx b/packages/hooks/src/useVirtualList/demo/demo1.tsx index d1ed1e2db1..d4d1335cd8 100644 --- a/packages/hooks/src/useVirtualList/demo/demo1.tsx +++ b/packages/hooks/src/useVirtualList/demo/demo1.tsx @@ -6,8 +6,8 @@ * desc.zh-CN: 渲染大量数据 */ -import { useMemo, useRef } from 'react'; -import { useVirtualList } from 'ahooks'; +import { useMemo, useRef } from "react"; +import { useVirtualList } from "ahooks"; export default () => { const containerRef = useRef(null); @@ -23,16 +23,19 @@ export default () => { }); return ( <> -
+
{list.map((ele) => (
{ - test('isBoolean', () => { +describe("shared utils methods", () => { + test("isBoolean", () => { expect(isBoolean(true)).toBe(true); expect(isBoolean(false)).toBe(true); - expect(isBoolean('')).toBe(false); + expect(isBoolean("")).toBe(false); expect(isBoolean([])).toBe(false); }); - test('isFunction', () => { + test("isFunction", () => { expect(isFunction(function foo() {})).toBe(true); expect(isFunction(() => {})).toBe(true); @@ -18,16 +25,16 @@ describe('shared utils methods', () => { expect(isFunction(1)).toBe(false); }); - test('isNumber', () => { + test("isNumber", () => { expect(isNumber(1)).toBe(true); expect(isNumber(Infinity)).toBe(true); expect(isNumber(NaN)).toBe(true); - expect(isNumber('str')).toBe(false); + expect(isNumber("str")).toBe(false); expect(isNumber({})).toBe(false); }); - test('isObject', () => { + test("isObject", () => { expect(isObject({})).toBe(true); expect(isObject([])).toBe(true); expect(isObject(/(?:)/)).toBe(true); @@ -38,20 +45,20 @@ describe('shared utils methods', () => { expect(isObject(123)).toBe(false); }); - test('isString', () => { - expect(isString('1')).toBe(true); - expect(isString(String('1'))).toBe(true); + test("isString", () => { + expect(isString("1")).toBe(true); + expect(isString(String("1"))).toBe(true); expect(isString(1)).toBe(false); expect(isString({})).toBe(false); }); - test('isUndef', () => { + test("isUndef", () => { expect(isUndef(undefined)).toBe(true); expect(isUndef(0)).toBe(false); expect(isUndef(null)).toBe(false); expect(isUndef(NaN)).toBe(false); - expect(isUndef('')).toBe(false); + expect(isUndef("")).toBe(false); }); }); diff --git a/packages/hooks/src/utils/index.ts b/packages/hooks/src/utils/index.ts index 9cc2bcc7d3..7a75c0f254 100644 --- a/packages/hooks/src/utils/index.ts +++ b/packages/hooks/src/utils/index.ts @@ -1,8 +1,12 @@ export const isObject = (value: unknown): value is Record => - value !== null && typeof value === 'object'; + value !== null && typeof value === "object"; export const isFunction = (value: unknown): value is (...args: any) => any => - typeof value === 'function'; -export const isString = (value: unknown): value is string => typeof value === 'string'; -export const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean'; -export const isNumber = (value: unknown): value is number => typeof value === 'number'; -export const isUndef = (value: unknown): value is undefined => typeof value === 'undefined'; + typeof value === "function"; +export const isString = (value: unknown): value is string => + typeof value === "string"; +export const isBoolean = (value: unknown): value is boolean => + typeof value === "boolean"; +export const isNumber = (value: unknown): value is number => + typeof value === "number" && !Number.isNaN(value); +export const isUndef = (value: unknown): value is undefined => + typeof value === "undefined"; From c107f6863fed57beefa31b2516a50737795b2ff2 Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Tue, 14 Apr 2026 07:14:00 +0800 Subject: [PATCH 2/4] fix: refines number type check --- packages/hooks/src/useCountDown/index.ts | 14 ++++---- .../hooks/src/useVirtualList/demo/demo1.tsx | 17 ++++----- .../hooks/src/utils/__tests__/index.spec.ts | 35 ++++++++----------- packages/hooks/src/utils/index.ts | 15 ++++---- 4 files changed, 33 insertions(+), 48 deletions(-) diff --git a/packages/hooks/src/useCountDown/index.ts b/packages/hooks/src/useCountDown/index.ts index bc5516edcb..2ed638e4d5 100644 --- a/packages/hooks/src/useCountDown/index.ts +++ b/packages/hooks/src/useCountDown/index.ts @@ -1,7 +1,7 @@ -import dayjs from "dayjs"; -import { useEffect, useMemo, useState } from "react"; -import useLatest from "../useLatest"; -import { isNumber } from "../utils"; +import dayjs from 'dayjs'; +import { useEffect, useMemo, useState } from 'react'; +import useLatest from '../useLatest'; +import { isNumber } from '../utils'; export type TDate = dayjs.ConfigType; @@ -43,12 +43,10 @@ const useCountdown = (options: Options = {}) => { const { leftTime, targetDate, interval = 1000, onEnd } = options || {}; const memoLeftTime = useMemo(() => { - return isNumber(leftTime) && leftTime > 0 - ? Date.now() + leftTime - : undefined; + return isNumber(leftTime) && leftTime > 0 ? Date.now() + leftTime : undefined; }, [leftTime]); - const target = "leftTime" in options ? memoLeftTime : targetDate; + const target = 'leftTime' in options ? memoLeftTime : targetDate; const [timeLeft, setTimeLeft] = useState(() => calcLeft(target)); diff --git a/packages/hooks/src/useVirtualList/demo/demo1.tsx b/packages/hooks/src/useVirtualList/demo/demo1.tsx index d4d1335cd8..d1ed1e2db1 100644 --- a/packages/hooks/src/useVirtualList/demo/demo1.tsx +++ b/packages/hooks/src/useVirtualList/demo/demo1.tsx @@ -6,8 +6,8 @@ * desc.zh-CN: 渲染大量数据 */ -import { useMemo, useRef } from "react"; -import { useVirtualList } from "ahooks"; +import { useMemo, useRef } from 'react'; +import { useVirtualList } from 'ahooks'; export default () => { const containerRef = useRef(null); @@ -23,19 +23,16 @@ export default () => { }); return ( <> -
+
{list.map((ele) => (
{ - test("isBoolean", () => { +describe('shared utils methods', () => { + test('isBoolean', () => { expect(isBoolean(true)).toBe(true); expect(isBoolean(false)).toBe(true); - expect(isBoolean("")).toBe(false); + expect(isBoolean('')).toBe(false); expect(isBoolean([])).toBe(false); }); - test("isFunction", () => { + test('isFunction', () => { expect(isFunction(function foo() {})).toBe(true); expect(isFunction(() => {})).toBe(true); @@ -25,16 +18,16 @@ describe("shared utils methods", () => { expect(isFunction(1)).toBe(false); }); - test("isNumber", () => { + test('isNumber', () => { expect(isNumber(1)).toBe(true); expect(isNumber(Infinity)).toBe(true); expect(isNumber(NaN)).toBe(true); - expect(isNumber("str")).toBe(false); + expect(isNumber('str')).toBe(false); expect(isNumber({})).toBe(false); }); - test("isObject", () => { + test('isObject', () => { expect(isObject({})).toBe(true); expect(isObject([])).toBe(true); expect(isObject(/(?:)/)).toBe(true); @@ -45,20 +38,20 @@ describe("shared utils methods", () => { expect(isObject(123)).toBe(false); }); - test("isString", () => { - expect(isString("1")).toBe(true); - expect(isString(String("1"))).toBe(true); + test('isString', () => { + expect(isString('1')).toBe(true); + expect(isString(String('1'))).toBe(true); expect(isString(1)).toBe(false); expect(isString({})).toBe(false); }); - test("isUndef", () => { + test('isUndef', () => { expect(isUndef(undefined)).toBe(true); expect(isUndef(0)).toBe(false); expect(isUndef(null)).toBe(false); expect(isUndef(NaN)).toBe(false); - expect(isUndef("")).toBe(false); + expect(isUndef('')).toBe(false); }); }); diff --git a/packages/hooks/src/utils/index.ts b/packages/hooks/src/utils/index.ts index 7a75c0f254..0ffea4fade 100644 --- a/packages/hooks/src/utils/index.ts +++ b/packages/hooks/src/utils/index.ts @@ -1,12 +1,9 @@ export const isObject = (value: unknown): value is Record => - value !== null && typeof value === "object"; + value !== null && typeof value === 'object'; export const isFunction = (value: unknown): value is (...args: any) => any => - typeof value === "function"; -export const isString = (value: unknown): value is string => - typeof value === "string"; -export const isBoolean = (value: unknown): value is boolean => - typeof value === "boolean"; + typeof value === 'function'; +export const isString = (value: unknown): value is string => typeof value === 'string'; +export const isBoolean = (value: unknown): value is boolean => typeof value === 'boolean'; export const isNumber = (value: unknown): value is number => - typeof value === "number" && !Number.isNaN(value); -export const isUndef = (value: unknown): value is undefined => - typeof value === "undefined"; + typeof value === 'number' && !Number.isNaN(value); +export const isUndef = (value: unknown): value is undefined => typeof value === 'undefined'; From 3a15f9375b760c38b722e2ea0be8787d3f78dc0e Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Tue, 14 Apr 2026 07:22:03 +0800 Subject: [PATCH 3/4] test: update test case --- .../hooks/src/utils/__tests__/index.spec.ts | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/packages/hooks/src/utils/__tests__/index.spec.ts b/packages/hooks/src/utils/__tests__/index.spec.ts index 0872d72238..eee72d7f0d 100644 --- a/packages/hooks/src/utils/__tests__/index.spec.ts +++ b/packages/hooks/src/utils/__tests__/index.spec.ts @@ -1,16 +1,23 @@ -import { describe, expect, test } from 'vitest'; -import { isBoolean, isFunction, isNumber, isObject, isString, isUndef } from '../'; +import { describe, expect, test } from "vitest"; +import { + isBoolean, + isFunction, + isNumber, + isObject, + isString, + isUndef, +} from "../"; -describe('shared utils methods', () => { - test('isBoolean', () => { +describe("shared utils methods", () => { + test("isBoolean", () => { expect(isBoolean(true)).toBe(true); expect(isBoolean(false)).toBe(true); - expect(isBoolean('')).toBe(false); + expect(isBoolean("")).toBe(false); expect(isBoolean([])).toBe(false); }); - test('isFunction', () => { + test("isFunction", () => { expect(isFunction(function foo() {})).toBe(true); expect(isFunction(() => {})).toBe(true); @@ -18,16 +25,16 @@ describe('shared utils methods', () => { expect(isFunction(1)).toBe(false); }); - test('isNumber', () => { + test("isNumber", () => { expect(isNumber(1)).toBe(true); expect(isNumber(Infinity)).toBe(true); - expect(isNumber(NaN)).toBe(true); + expect(isNumber(NaN)).toBe(false); - expect(isNumber('str')).toBe(false); + expect(isNumber("str")).toBe(false); expect(isNumber({})).toBe(false); }); - test('isObject', () => { + test("isObject", () => { expect(isObject({})).toBe(true); expect(isObject([])).toBe(true); expect(isObject(/(?:)/)).toBe(true); @@ -38,20 +45,20 @@ describe('shared utils methods', () => { expect(isObject(123)).toBe(false); }); - test('isString', () => { - expect(isString('1')).toBe(true); - expect(isString(String('1'))).toBe(true); + test("isString", () => { + expect(isString("1")).toBe(true); + expect(isString(String("1"))).toBe(true); expect(isString(1)).toBe(false); expect(isString({})).toBe(false); }); - test('isUndef', () => { + test("isUndef", () => { expect(isUndef(undefined)).toBe(true); expect(isUndef(0)).toBe(false); expect(isUndef(null)).toBe(false); expect(isUndef(NaN)).toBe(false); - expect(isUndef('')).toBe(false); + expect(isUndef("")).toBe(false); }); }); From 597c0ded171e24ee0d7334d28be95543082b4f76 Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Tue, 14 Apr 2026 07:22:07 +0800 Subject: [PATCH 4/4] test: update test case --- .../hooks/src/utils/__tests__/index.spec.ts | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/packages/hooks/src/utils/__tests__/index.spec.ts b/packages/hooks/src/utils/__tests__/index.spec.ts index eee72d7f0d..5c96cd79c2 100644 --- a/packages/hooks/src/utils/__tests__/index.spec.ts +++ b/packages/hooks/src/utils/__tests__/index.spec.ts @@ -1,23 +1,16 @@ -import { describe, expect, test } from "vitest"; -import { - isBoolean, - isFunction, - isNumber, - isObject, - isString, - isUndef, -} from "../"; +import { describe, expect, test } from 'vitest'; +import { isBoolean, isFunction, isNumber, isObject, isString, isUndef } from '../'; -describe("shared utils methods", () => { - test("isBoolean", () => { +describe('shared utils methods', () => { + test('isBoolean', () => { expect(isBoolean(true)).toBe(true); expect(isBoolean(false)).toBe(true); - expect(isBoolean("")).toBe(false); + expect(isBoolean('')).toBe(false); expect(isBoolean([])).toBe(false); }); - test("isFunction", () => { + test('isFunction', () => { expect(isFunction(function foo() {})).toBe(true); expect(isFunction(() => {})).toBe(true); @@ -25,16 +18,16 @@ describe("shared utils methods", () => { expect(isFunction(1)).toBe(false); }); - test("isNumber", () => { + test('isNumber', () => { expect(isNumber(1)).toBe(true); expect(isNumber(Infinity)).toBe(true); expect(isNumber(NaN)).toBe(false); - expect(isNumber("str")).toBe(false); + expect(isNumber('str')).toBe(false); expect(isNumber({})).toBe(false); }); - test("isObject", () => { + test('isObject', () => { expect(isObject({})).toBe(true); expect(isObject([])).toBe(true); expect(isObject(/(?:)/)).toBe(true); @@ -45,20 +38,20 @@ describe("shared utils methods", () => { expect(isObject(123)).toBe(false); }); - test("isString", () => { - expect(isString("1")).toBe(true); - expect(isString(String("1"))).toBe(true); + test('isString', () => { + expect(isString('1')).toBe(true); + expect(isString(String('1'))).toBe(true); expect(isString(1)).toBe(false); expect(isString({})).toBe(false); }); - test("isUndef", () => { + test('isUndef', () => { expect(isUndef(undefined)).toBe(true); expect(isUndef(0)).toBe(false); expect(isUndef(null)).toBe(false); expect(isUndef(NaN)).toBe(false); - expect(isUndef("")).toBe(false); + expect(isUndef('')).toBe(false); }); });