@pawover/kit 0.4.1 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "https://github.com/pawover"
7
7
  },
8
8
  "description": "一个基于 TypeScript 的开发工具包",
9
- "version": "0.4.1",
9
+ "version": "0.5.1",
10
10
  "type": "module",
11
11
  "engines": {
12
12
  "node": ">=22.20.0"
@@ -14,7 +14,7 @@
14
14
  "devEngines": {
15
15
  "runtime": {
16
16
  "name": "node",
17
- "version": "24.14.0"
17
+ "version": "24.18.0"
18
18
  }
19
19
  },
20
20
  "keywords": [
@@ -27,7 +27,7 @@
27
27
  "url": "git+https://github.com/pawover/pawover-kit.git"
28
28
  },
29
29
  "license": "MIT",
30
- "main": "./packages/utils/dist/index.js",
30
+ "main": "./packages/utils/dist/index.cjs",
31
31
  "module": "./packages/utils/dist/index.js",
32
32
  "types": "./packages/utils/dist/index.d.ts",
33
33
  "files": [
@@ -36,48 +36,152 @@
36
36
  "packages/zod/dist"
37
37
  ],
38
38
  "exports": {
39
- ".": "./packages/utils/dist/index.js",
40
- "./math": "./packages/utils/dist/math.js",
41
- "./vite": "./packages/utils/dist/vite.js",
39
+ ".": {
40
+ "import": {
41
+ "types": "./packages/utils/dist/index.d.ts",
42
+ "default": "./packages/utils/dist/index.js"
43
+ },
44
+ "require": {
45
+ "types": "./packages/utils/dist/index.d.cts",
46
+ "default": "./packages/utils/dist/index.cjs"
47
+ }
48
+ },
49
+ "./math": {
50
+ "import": {
51
+ "types": "./packages/utils/dist/math.d.ts",
52
+ "default": "./packages/utils/dist/math.js"
53
+ },
54
+ "require": {
55
+ "types": "./packages/utils/dist/math.d.cts",
56
+ "default": "./packages/utils/dist/math.cjs"
57
+ }
58
+ },
59
+ "./vite": {
60
+ "import": {
61
+ "types": "./packages/utils/dist/vite.d.ts",
62
+ "default": "./packages/utils/dist/vite.js"
63
+ },
64
+ "require": {
65
+ "types": "./packages/utils/dist/vite.d.cts",
66
+ "default": "./packages/utils/dist/vite.cjs"
67
+ }
68
+ },
42
69
  "./metadata.json": "./packages/utils/dist/metadata.json",
43
- "./utils": "./packages/utils/dist/index.js",
44
- "./utils/math": "./packages/utils/dist/math.js",
45
- "./utils/vite": "./packages/utils/dist/vite.js",
46
- "./utils/*": "./packages/utils/dist/*",
47
- "./hooks/alova": "./packages/hooks/dist/alova.js",
48
- "./hooks/react": "./packages/hooks/dist/react.js",
49
- "./hooks/*": "./packages/hooks/dist/*",
50
- "./zod": "./packages/zod/dist/index.js",
51
- "./zod/*": "./packages/zod/dist/*"
70
+ "./utils": {
71
+ "import": {
72
+ "types": "./packages/utils/dist/index.d.ts",
73
+ "default": "./packages/utils/dist/index.js"
74
+ },
75
+ "require": {
76
+ "types": "./packages/utils/dist/index.d.cts",
77
+ "default": "./packages/utils/dist/index.cjs"
78
+ }
79
+ },
80
+ "./utils/math": {
81
+ "import": {
82
+ "types": "./packages/utils/dist/math.d.ts",
83
+ "default": "./packages/utils/dist/math.js"
84
+ },
85
+ "require": {
86
+ "types": "./packages/utils/dist/math.d.cts",
87
+ "default": "./packages/utils/dist/math.cjs"
88
+ }
89
+ },
90
+ "./utils/vite": {
91
+ "import": {
92
+ "types": "./packages/utils/dist/vite.d.ts",
93
+ "default": "./packages/utils/dist/vite.js"
94
+ },
95
+ "require": {
96
+ "types": "./packages/utils/dist/vite.d.cts",
97
+ "default": "./packages/utils/dist/vite.cjs"
98
+ }
99
+ },
100
+ "./utils/*": {
101
+ "import": {
102
+ "types": "./packages/utils/dist/*",
103
+ "default": "./packages/utils/dist/*"
104
+ },
105
+ "require": "./packages/utils/dist/*"
106
+ },
107
+ "./hooks/alova": {
108
+ "import": {
109
+ "types": "./packages/hooks/dist/alova.d.ts",
110
+ "default": "./packages/hooks/dist/alova.js"
111
+ },
112
+ "require": {
113
+ "types": "./packages/hooks/dist/alova.d.cts",
114
+ "default": "./packages/hooks/dist/alova.cjs"
115
+ }
116
+ },
117
+ "./hooks/react": {
118
+ "import": {
119
+ "types": "./packages/hooks/dist/react.d.ts",
120
+ "default": "./packages/hooks/dist/react.js"
121
+ },
122
+ "require": {
123
+ "types": "./packages/hooks/dist/react.d.cts",
124
+ "default": "./packages/hooks/dist/react.cjs"
125
+ }
126
+ },
127
+ "./hooks/*": {
128
+ "import": {
129
+ "types": "./packages/hooks/dist/*",
130
+ "default": "./packages/hooks/dist/*"
131
+ },
132
+ "require": "./packages/hooks/dist/*"
133
+ },
134
+ "./zod": {
135
+ "import": {
136
+ "types": "./packages/zod/dist/index.d.ts",
137
+ "default": "./packages/zod/dist/index.js"
138
+ },
139
+ "require": {
140
+ "types": "./packages/zod/dist/index.d.cts",
141
+ "default": "./packages/zod/dist/index.cjs"
142
+ }
143
+ },
144
+ "./zod/*": {
145
+ "import": {
146
+ "types": "./packages/zod/dist/*",
147
+ "default": "./packages/zod/dist/*"
148
+ },
149
+ "require": "./packages/zod/dist/*"
150
+ }
52
151
  },
53
152
  "devDependencies": {
54
153
  "@commitlint/cli": "^21.2.1",
55
154
  "@commitlint/config-conventional": "^21.2.0",
56
- "@eslint-react/eslint-plugin": "^5.17.3",
155
+ "@eslint-react/eslint-plugin": "^5.18.2",
57
156
  "@pawover/eslint-rules": "^0.2.3",
58
- "@playwright/test": "^1.61.1",
157
+ "@playwright/test": "^1.62.1",
59
158
  "@stylistic/eslint-plugin": "^6.0.0-beta.5",
159
+ "@testing-library/react": "^16.3.2",
60
160
  "@types/fs-extra": "^11.0.4",
61
- "@types/node": "^26.1.1",
62
- "@vitejs/plugin-react": "^6.0.4",
161
+ "@types/node": "^26.1.2",
162
+ "@types/react": "^19.2.18",
163
+ "@vitejs/plugin-react": "^6.0.5",
63
164
  "@vitest/browser-playwright": "^4.1.10",
165
+ "@vitest/coverage-v8": "^4.1.10",
166
+ "alova": "^3.5.1",
64
167
  "commitizen": "^4.3.2",
65
168
  "cz-customizable": "^7.5.4",
66
- "eslint": "^10.7.0",
169
+ "eslint": "^10.8.0",
67
170
  "eslint-plugin-antfu": "^3.2.3",
68
171
  "eslint-plugin-import-lite": "^0.6.0",
69
172
  "eslint-plugin-react-hooks": "^7.1.1",
70
- "fs-extra": "^11.3.6",
173
+ "fs-extra": "^11.4.0",
71
174
  "husky": "^9.1.7",
72
- "jsdom": "^29.1.1",
73
- "lint-staged": "^17.1.1",
175
+ "jsdom": "^30.0.1",
176
+ "lint-staged": "^17.3.0",
177
+ "mathjs": "^15.2.0",
74
178
  "prettier": "^3.9.6",
179
+ "react-dom": "19.2.6",
75
180
  "rimraf": "^6.1.3",
76
- "taze": "^19.16.0",
77
- "tsdown": "^0.22.13",
78
- "turbo": "^2.10.5",
181
+ "tsdown": "^0.22.14",
182
+ "turbo": "^2.10.8",
79
183
  "typescript": "^6.0.3",
80
- "typescript-eslint": "^8.65.0",
184
+ "typescript-eslint": "^8.66.0",
81
185
  "vitest": "^4.1.10"
82
186
  },
83
187
  "peerDependencies": {
@@ -113,7 +217,14 @@
113
217
  }
114
218
  },
115
219
  "scripts": {
116
- "test": "vitest",
220
+ "test": "vitest run",
221
+ "test:watch": "vitest",
222
+ "test:coverage": "vitest run --coverage",
223
+ "test:unit": "vitest run test/unit",
224
+ "test:integration": "vitest run test/integration",
225
+ "test:types": "tsc -p test/tsconfig.json --noEmit",
226
+ "test:smoke": "node test/scripts/smoke.mjs",
227
+ "test:ci": "pnpm test:types && pnpm test && pnpm build && pnpm test:smoke && pnpm check:pack",
117
228
  "build": "turbo build",
118
229
  "build:force": "turbo build --force",
119
230
  "build:package": "turbo build:package && pnpm package",
@@ -124,13 +235,13 @@
124
235
  "check:types": "tsc --noEmit",
125
236
  "check:eslint": "eslint --fix \"**/*.{js,cjs,mjs,ts,cts,mts,jsx,tsx,vue}\" --cache-location=.cache/eslint.cache.json --cache",
126
237
  "check:format": "prettier --write \"**/*.{html,json,jsonc}\" --cache-location=.cache/prettier.cache.json --cache",
127
- "check:pack": "attw --pack .",
238
+ "check:pack": "pnpm dlx @arethetypeswrong/cli --pack . --profile node16",
128
239
  "clean": "pnpm clean:cache & pnpm clean:lib & pnpm clean:output",
129
240
  "clean:turbo": "rimraf -g **/.turbo",
130
241
  "clean:cache": "rimraf -g .cache",
131
242
  "clean:lib": "rimraf -g node_modules",
132
243
  "clean:output": "rimraf -g **/dist **/*.tgz",
133
- "lib:up": "taze -I -r --exclude pnpm",
244
+ "lib:up": "pnpm dlx taze -I -r --exclude pnpm",
134
245
  "commit": "git cz"
135
246
  }
136
247
  }
@@ -0,0 +1,53 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let alova_client = require("alova/client");
3
+ //#region src/alova/createBeforeRequestMiddleware.ts
4
+ function createBeforeRequestMiddleware(middleware, onBeforeRequest) {
5
+ return async (context, next) => {
6
+ onBeforeRequest?.(context);
7
+ if (middleware) return middleware(context, next);
8
+ return next();
9
+ };
10
+ }
11
+ //#endregion
12
+ //#region src/alova/useAlovaPagination.ts
13
+ function useAlovaPagination(methodHandler, hookOptions) {
14
+ const options = {
15
+ ...hookOptions,
16
+ immediate: hookOptions?.immediate ?? true
17
+ };
18
+ if (options.onBeforeRequest) options.middleware = createBeforeRequestMiddleware(options.middleware, options.onBeforeRequest);
19
+ const exposure = (0, alova_client.usePagination)(methodHandler, options);
20
+ if (options.onSuccess) exposure.onSuccess(options.onSuccess);
21
+ if (options.onError) exposure.onError(options.onError);
22
+ if (options.onComplete) exposure.onComplete(options.onComplete);
23
+ return exposure;
24
+ }
25
+ //#endregion
26
+ //#region src/alova/useAlovaRequest.ts
27
+ function useAlovaRequest(methodHandler, hookOptions) {
28
+ const options = {
29
+ ...hookOptions,
30
+ immediate: hookOptions?.immediate ?? true
31
+ };
32
+ if (options.onBeforeRequest) options.middleware = createBeforeRequestMiddleware(options.middleware, options.onBeforeRequest);
33
+ const exposure = (0, alova_client.useRequest)(methodHandler, options);
34
+ if (options.onSuccess) exposure.onSuccess(options.onSuccess);
35
+ if (options.onError) exposure.onError(options.onError);
36
+ if (options.onComplete) exposure.onComplete(options.onComplete);
37
+ return exposure;
38
+ }
39
+ //#endregion
40
+ //#region src/alova/useAlovaWatcher.ts
41
+ function useAlovaWatcher(methodHandler, watchingStates, hookOptions = {}) {
42
+ const options = { ...hookOptions };
43
+ if (options.onBeforeRequest) options.middleware = createBeforeRequestMiddleware(options.middleware, options.onBeforeRequest);
44
+ const exposure = (0, alova_client.useWatcher)(methodHandler, watchingStates, options);
45
+ if (options.onSuccess) exposure.onSuccess(options.onSuccess);
46
+ if (options.onError) exposure.onError(options.onError);
47
+ if (options.onComplete) exposure.onComplete(options.onComplete);
48
+ return exposure;
49
+ }
50
+ //#endregion
51
+ exports.useAlovaPagination = useAlovaPagination;
52
+ exports.useAlovaRequest = useAlovaRequest;
53
+ exports.useAlovaWatcher = useAlovaWatcher;
@@ -0,0 +1 @@
1
+ export type * from './alova.d.ts'
File without changes
@@ -0,0 +1 @@
1
+ export type * from './index.d.ts'
@@ -0,0 +1,169 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let react = require("react");
3
+ let _pawover_kit_utils = require("@pawover/kit-utils");
4
+ let es_toolkit = require("es-toolkit");
5
+ //#region src/react/useLatest.ts
6
+ /**
7
+ * 返回当前最新值的 Hook
8
+ *
9
+ * @param value
10
+ */
11
+ function useLatest(value) {
12
+ const ref = (0, react.useRef)(value);
13
+ ref.current = value;
14
+ return ref;
15
+ }
16
+ //#endregion
17
+ //#region src/react/useMount.ts
18
+ /**
19
+ * 在组件初始化时执行的 Hook
20
+ * - 即使在严格模式(React StrictMode)也只执行一次
21
+ * - 自动使用最新版 effect 函数
22
+ *
23
+ * @param effect 副作用函数(必须为同步函数;若为异步函数,清理逻辑需自行处理)
24
+ * @example
25
+ * useMount(() => {
26
+ * console.log('组件挂载');
27
+ * return () => console.log('组件卸载');
28
+ * });
29
+ *
30
+ * useMount(async () => {
31
+ * const data = await fetchData();
32
+ * // 清理逻辑需通过 ref/AbortController 自行管理
33
+ * // ❌ 不要 return cleanupFn(async 函数返回 Promise,无法作为清理函数)
34
+ * });
35
+ */
36
+ function useMount(effect) {
37
+ const isMountedRef = (0, react.useRef)(false);
38
+ const effectRef = useLatest(effect);
39
+ (0, react.useEffect)(() => {
40
+ if (!_pawover_kit_utils.TypeUtil.isFunction(effectRef.current)) {
41
+ console.error(`hook [useMount] Expected parameter to be a function, but got ${typeof effectRef.current}. This effect will not execute.`);
42
+ return;
43
+ }
44
+ if (isMountedRef.current) return;
45
+ isMountedRef.current = true;
46
+ const cleanup = effectRef.current?.();
47
+ return _pawover_kit_utils.TypeUtil.isFunction(cleanup) && !_pawover_kit_utils.TypeUtil.isPromise(cleanup) ? cleanup : void 0;
48
+ }, [effectRef]);
49
+ }
50
+ //#endregion
51
+ //#region src/react/useResponsive.ts
52
+ /** 屏幕响应断点 token 配置 */
53
+ const BREAK_POINT_TOKEN = {
54
+ XS: 480,
55
+ XSMax: 575,
56
+ XSMin: 480,
57
+ SM: 576,
58
+ SMMax: 767,
59
+ SMMin: 576,
60
+ MD: 768,
61
+ MDMax: 991,
62
+ MDMin: 768,
63
+ LG: 992,
64
+ LGMax: 1199,
65
+ LGMin: 992,
66
+ XL: 1200,
67
+ XLMax: 1599,
68
+ XLMin: 1200,
69
+ XXL: 1600,
70
+ XXLMax: 1919,
71
+ XXLMin: 1600,
72
+ XXXL: 1920,
73
+ XXXLMin: 1920
74
+ };
75
+ const SUBSCRIBER_SET = /* @__PURE__ */ new Set();
76
+ const BREAK_POINTS = [
77
+ "xxxl",
78
+ "xxl",
79
+ "xl",
80
+ "lg",
81
+ "md",
82
+ "sm",
83
+ "xs"
84
+ ];
85
+ const DEFAULT_VALUES = Object.freeze(_pawover_kit_utils.ArrayUtil.zipToObject(BREAK_POINTS, false));
86
+ let responsiveValues = { ...DEFAULT_VALUES };
87
+ let responsiveTokens = (0, es_toolkit.clone)(BREAK_POINT_TOKEN);
88
+ function useResponsive(options) {
89
+ const { breakPointTokens = {} } = options || {};
90
+ const tokens = (0, react.useMemo)(() => Object.assign(BREAK_POINT_TOKEN, breakPointTokens), [breakPointTokens]);
91
+ const [responsive, setResponsive] = (0, react.useState)(() => calculateResponsive(tokens));
92
+ const current = _pawover_kit_utils.ObjectUtil.keys(DEFAULT_VALUES).find((key) => responsive[key] === true) || "xs";
93
+ (0, react.useLayoutEffect)(() => {
94
+ responsiveTokens = tokens;
95
+ window.addEventListener("resize", resizeListener);
96
+ const subscriber = () => {
97
+ setResponsive(responsiveValues);
98
+ };
99
+ SUBSCRIBER_SET.add(subscriber);
100
+ return () => {
101
+ SUBSCRIBER_SET.delete(subscriber);
102
+ if (!SUBSCRIBER_SET.size) window.removeEventListener("resize", resizeListener);
103
+ };
104
+ }, [tokens]);
105
+ return {
106
+ responsive,
107
+ current,
108
+ breakPointTokens: tokens
109
+ };
110
+ }
111
+ function resizeListener() {
112
+ const newValues = calculateResponsive(responsiveTokens);
113
+ if (!(0, es_toolkit.isEqual)(responsiveValues, newValues)) {
114
+ responsiveValues = newValues;
115
+ for (const subscriber of SUBSCRIBER_SET) subscriber();
116
+ }
117
+ }
118
+ function calculateResponsive(tokens) {
119
+ const config = _pawover_kit_utils.ArrayUtil.zipToObject(BREAK_POINTS, BREAK_POINTS.map((t) => tokens[_pawover_kit_utils.StringUtil.toUpperCase(t)]));
120
+ return _pawover_kit_utils.ObjectUtil.entriesMap(DEFAULT_VALUES, (key) => [key, window.innerWidth >= config[key]]);
121
+ }
122
+ //#endregion
123
+ //#region src/react/useUnmount.ts
124
+ /**
125
+ * 在组件卸载时执行的 Hook
126
+ *
127
+ * @param effect 副作用函数
128
+ */
129
+ function useUnmount(effect) {
130
+ const effectRef = useLatest(effect);
131
+ (0, react.useEffect)(() => () => {
132
+ if (!_pawover_kit_utils.TypeUtil.isFunction(effectRef.current)) {
133
+ console.error(`hook [useUnmount] Expected parameter to be a function, but got ${typeof effectRef.current}. This effect will not execute.`);
134
+ return;
135
+ }
136
+ effectRef.current?.();
137
+ }, [effectRef]);
138
+ }
139
+ //#endregion
140
+ //#region src/react/useTitle.ts
141
+ /**
142
+ * 设置页面标题
143
+ * - 轻量级,适用于无路由库时设置页面标题
144
+ * - 多个 `useTitle` 实例会互相干扰,需在顶层组件使用
145
+ * - 无法处理 `document.title` 固有的竞态问题
146
+ *
147
+ * @param title 页面标题
148
+ * @param options 配置选项
149
+ */
150
+ function useTitle(title, options) {
151
+ const titleRef = (0, react.useRef)(_pawover_kit_utils.EnvUtil.isBrowser() ? document.title : "");
152
+ (0, react.useEffect)(() => {
153
+ if (!_pawover_kit_utils.TypeUtil.isString(title)) {
154
+ console.error(`hook [useTitle] Expected parameter to be a string, but got ${typeof title}. This effect will not execute.`);
155
+ return;
156
+ }
157
+ if (_pawover_kit_utils.EnvUtil.isBrowser()) document.title = title;
158
+ }, [title]);
159
+ useUnmount(() => {
160
+ if (_pawover_kit_utils.EnvUtil.isBrowser() && options?.isRestoreOnUnmount) document.title = titleRef.current;
161
+ });
162
+ }
163
+ //#endregion
164
+ exports.BREAK_POINT_TOKEN = BREAK_POINT_TOKEN;
165
+ exports.useLatest = useLatest;
166
+ exports.useMount = useMount;
167
+ exports.useResponsive = useResponsive;
168
+ exports.useTitle = useTitle;
169
+ exports.useUnmount = useUnmount;
@@ -0,0 +1 @@
1
+ export type * from './react.d.ts'
@@ -1,4 +1,6 @@
1
1
  import { EffectCallback, RefObject } from "react";
2
+ import { AnyAsyncFunction, AnyFunction } from "@pawover/types";
3
+ import { TupleToUnion } from "type-fest";
2
4
  //#region src/react/useLatest.d.ts
3
5
  /**
4
6
  * 返回当前最新值的 Hook
@@ -7,12 +9,6 @@ import { EffectCallback, RefObject } from "react";
7
9
  */
8
10
  declare function useLatest<T>(value: T): RefObject<T>;
9
11
  //#endregion
10
- //#region ../../node_modules/.pnpm/@pawover+types@0.0.4_@types+react@19.2.15_typescript@6.0.3/node_modules/@pawover/types/dist/index.d.ts
11
- /** 描述函数类型 */
12
- type AnyFunction<P extends any[] = any[], R = any> = (...arg: P) => R;
13
- /** 描述异步函数类型 */
14
- type AnyAsyncFunction<P extends any[] = any[], R = any> = (...args: P) => Promise<R>;
15
- //#endregion
16
12
  //#region src/react/useMount.d.ts
17
13
  /**
18
14
  * 在组件初始化时执行的 Hook
@@ -34,60 +30,6 @@ type AnyAsyncFunction<P extends any[] = any[], R = any> = (...args: P) => Promis
34
30
  */
35
31
  declare function useMount(effect: EffectCallback | AnyAsyncFunction): void;
36
32
  //#endregion
37
- //#region ../../node_modules/.pnpm/type-fest@5.8.0/node_modules/type-fest/source/tuple-to-union.d.ts
38
- /**
39
- Convert a tuple/array into a union type of its elements.
40
-
41
- This can be useful when you have a fixed set of allowed values and want a type defining only the allowed values, but do not want to repeat yourself.
42
-
43
- @example
44
- ```
45
- import type {TupleToUnion} from 'type-fest';
46
-
47
- const destinations = ['a', 'b', 'c'] as const;
48
-
49
- type Destination = TupleToUnion<typeof destinations>;
50
- //=> 'a' | 'b' | 'c'
51
-
52
- function verifyDestination(destination: unknown): destination is Destination {
53
- return destinations.includes(destination as any);
54
- }
55
-
56
- type RequestBody = {
57
- deliverTo: Destination;
58
- };
59
-
60
- function verifyRequestBody(body: unknown): body is RequestBody {
61
- const {deliverTo} = (body as any);
62
- return typeof body === 'object' && body !== null && verifyDestination(deliverTo);
63
- }
64
- ```
65
-
66
- Alternatively, you may use `typeof destinations[number]`. If `destinations` is a tuple, there is no difference. However if `destinations` is a string, the resulting type will the union of the characters in the string. Other types of `destinations` may result in a compile error. In comparison, TupleToUnion will return `never` if a tuple is not provided.
67
-
68
- @example
69
- ```
70
- const destinations = ['a', 'b', 'c'] as const;
71
-
72
- type Destination = typeof destinations[number];
73
- //=> 'a' | 'b' | 'c'
74
-
75
- const erroringType = new Set(['a', 'b', 'c']);
76
-
77
- // @ts-expect-error
78
- type ErroringType = typeof erroringType[number];
79
- // Error: Type 'Set<string>' has no matching index signature for type 'number'. ts(2537)
80
-
81
- const numberBool: {[n: number]: boolean} = {1: true};
82
-
83
- type NumberBool = typeof numberBool[number];
84
- //=> boolean
85
- ```
86
-
87
- @category Array
88
- */
89
- type TupleToUnion<ArrayType> = ArrayType extends readonly unknown[] ? ArrayType[number] : never;
90
- //#endregion
91
33
  //#region src/react/useResponsive.d.ts
92
34
  type Breakpoint = TupleToUnion<typeof BREAK_POINTS>;
93
35
  type ResponsiveValues = Record<Breakpoint, boolean>;