@movk/core 0.0.3
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/LICENSE +21 -0
- package/README.md +204 -0
- package/dist/index.d.mts +1005 -0
- package/dist/index.d.ts +1005 -0
- package/dist/index.mjs +1 -0
- package/package.json +79 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1005 @@
|
|
|
1
|
+
import { VNode, Ref } from 'vue';
|
|
2
|
+
import { z } from 'zod/v4';
|
|
3
|
+
|
|
4
|
+
type AnyObject = Record<string, any>;
|
|
5
|
+
type OmitByKey<T, K extends keyof T> = {
|
|
6
|
+
[P in keyof T as P extends K ? never : P]: T[P];
|
|
7
|
+
};
|
|
8
|
+
type PickByKey<T, K extends keyof T> = {
|
|
9
|
+
[P in keyof T as P extends K ? P : never]: T[P];
|
|
10
|
+
};
|
|
11
|
+
type RenameKeys<T, Mapping extends {
|
|
12
|
+
[K in keyof T]?: PropertyKey;
|
|
13
|
+
}> = {
|
|
14
|
+
[K in keyof T as K extends keyof Mapping ? Exclude<Mapping[K], undefined> : K]: T[K];
|
|
15
|
+
};
|
|
16
|
+
type RequiredByKeys<T, K extends keyof T> = T & {
|
|
17
|
+
[P in K]-?: T[P];
|
|
18
|
+
};
|
|
19
|
+
type PartialByKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
20
|
+
type ReadonlyByKeys<T, K extends keyof T> = T & {
|
|
21
|
+
readonly [P in K]: T[P];
|
|
22
|
+
};
|
|
23
|
+
type MutableByKeys<T, K extends keyof T> = {
|
|
24
|
+
-readonly [P in K]: T[P];
|
|
25
|
+
} & Omit<T, K>;
|
|
26
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? {
|
|
27
|
+
[K in keyof I]: I[K];
|
|
28
|
+
} : never;
|
|
29
|
+
type FirstParam<T, K extends keyof T> = T[K] extends [infer P, ...any[]] ? P : never;
|
|
30
|
+
type FirstParameter<T> = T extends (arg: infer P, ...args: any[]) => any ? P : undefined;
|
|
31
|
+
type DeepPartial<T> = {
|
|
32
|
+
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P] | undefined;
|
|
33
|
+
};
|
|
34
|
+
type GetObjectField<MaybeObject, Key extends string> = MaybeObject extends Record<string, any> ? MaybeObject[Key] : never;
|
|
35
|
+
type StringOrVNode = string | VNode | (() => VNode);
|
|
36
|
+
|
|
37
|
+
declare const StorageTypeSchema: z.ZodEnum<{
|
|
38
|
+
localStorage: "localStorage";
|
|
39
|
+
sessionStorage: "sessionStorage";
|
|
40
|
+
}>;
|
|
41
|
+
type StorageType = z.infer<typeof StorageTypeSchema>;
|
|
42
|
+
declare function createStorageConfigSchema<T = unknown>(schema: z.ZodType<T>): z.ZodObject<{
|
|
43
|
+
key: z.ZodString;
|
|
44
|
+
schema: z.ZodCustom<z.ZodType<T, unknown, z.core.$ZodTypeInternals<T, unknown>>, z.ZodType<T, unknown, z.core.$ZodTypeInternals<T, unknown>>>;
|
|
45
|
+
defaultValue: z.ZodCustom<T, T>;
|
|
46
|
+
prefix: z.ZodDefault<z.ZodString>;
|
|
47
|
+
storage: z.ZodDefault<z.ZodEnum<{
|
|
48
|
+
localStorage: "localStorage";
|
|
49
|
+
sessionStorage: "sessionStorage";
|
|
50
|
+
}>>;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
type StorageConfig<T = unknown> = z.infer<ReturnType<typeof createStorageConfigSchema<T>>>;
|
|
53
|
+
type StorageConfigInput<T = unknown> = z.input<ReturnType<typeof createStorageConfigSchema<T>>>;
|
|
54
|
+
interface AppStorageReturn<T> {
|
|
55
|
+
state: Ref<T>;
|
|
56
|
+
getItem: () => T;
|
|
57
|
+
setItem: (value: T) => void;
|
|
58
|
+
removeItem: () => void;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
declare const _TreeNodeBaseSchema: z.ZodRecord<z.ZodString, z.ZodAny>;
|
|
62
|
+
type TreeNodeBase = z.infer<typeof _TreeNodeBaseSchema>;
|
|
63
|
+
type TreeNode<T extends TreeNodeBase = TreeNodeBase> = T & {
|
|
64
|
+
[K in TreeConfig['children']]: TreeNode<T>[];
|
|
65
|
+
};
|
|
66
|
+
declare const TreeConfigSchema: z.ZodObject<{
|
|
67
|
+
id: z.ZodDefault<z.ZodString>;
|
|
68
|
+
pid: z.ZodDefault<z.ZodString>;
|
|
69
|
+
children: z.ZodDefault<z.ZodString>;
|
|
70
|
+
}, z.core.$strip>;
|
|
71
|
+
type TreeConfig = z.infer<typeof TreeConfigSchema>;
|
|
72
|
+
type TreeConfigInput = z.input<typeof TreeConfigSchema>;
|
|
73
|
+
declare const TreeStatsSchema: z.ZodObject<{
|
|
74
|
+
total: z.ZodNumber;
|
|
75
|
+
leaves: z.ZodNumber;
|
|
76
|
+
depth: z.ZodNumber;
|
|
77
|
+
branches: z.ZodNumber;
|
|
78
|
+
}, z.core.$strip>;
|
|
79
|
+
type TreeStats = z.infer<typeof TreeStatsSchema>;
|
|
80
|
+
interface TreeNodeResult<T extends TreeNodeBase = TreeNodeBase> {
|
|
81
|
+
readonly node: TreeNode<T>;
|
|
82
|
+
readonly path: readonly TreeNode<T>[];
|
|
83
|
+
readonly depth: number;
|
|
84
|
+
readonly index: number;
|
|
85
|
+
}
|
|
86
|
+
type TreePredicate<T extends TreeNodeBase = TreeNodeBase> = (node: TreeNode<T>, depth: number, path: readonly TreeNode<T>[]) => boolean;
|
|
87
|
+
type TreeTransformer<T extends TreeNodeBase = TreeNodeBase, R extends TreeNodeBase = TreeNodeBase> = (node: TreeNode<T>, depth: number, path: readonly TreeNode<T>[]) => R;
|
|
88
|
+
type TreeVisitor<T extends TreeNodeBase = TreeNodeBase> = (node: TreeNode<T>, depth: number, path: readonly TreeNode<T>[]) => void | boolean;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 应用存储管理的组合式函数,支持localStorage和sessionStorage
|
|
92
|
+
*
|
|
93
|
+
* @category Composables
|
|
94
|
+
* @param config 存储配置对象
|
|
95
|
+
* @returns 存储管理对象,包含响应式状态和操作方法
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* import { z } from 'zod/v4'
|
|
99
|
+
*
|
|
100
|
+
* // 定义用户偏好设置的schema
|
|
101
|
+
* const userPrefsSchema = z.object({
|
|
102
|
+
* theme: z.enum(['light', 'dark']),
|
|
103
|
+
* language: z.string(),
|
|
104
|
+
* fontSize: z.number().min(12).max(24)
|
|
105
|
+
* })
|
|
106
|
+
*
|
|
107
|
+
* // 创建存储管理实例
|
|
108
|
+
* const { state, setItem, getItem, removeItem } = useAppStorage({
|
|
109
|
+
* key: 'user-preferences',
|
|
110
|
+
* defaultValue: {
|
|
111
|
+
* theme: 'light',
|
|
112
|
+
* language: 'zh-CN',
|
|
113
|
+
* fontSize: 16
|
|
114
|
+
* },
|
|
115
|
+
* schema: userPrefsSchema,
|
|
116
|
+
* storage: 'localStorage',
|
|
117
|
+
* prefix: 'app'
|
|
118
|
+
* })
|
|
119
|
+
*
|
|
120
|
+
* // 使用响应式状态
|
|
121
|
+
* console.log(state.value.theme) // 'light'
|
|
122
|
+
*
|
|
123
|
+
* // 更新设置
|
|
124
|
+
* setItem({
|
|
125
|
+
* theme: 'dark',
|
|
126
|
+
* language: 'en-US',
|
|
127
|
+
* fontSize: 18
|
|
128
|
+
* })
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
declare function useAppStorage<T = unknown>(config: StorageConfigInput<T>): AppStorageReturn<T>;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* 复制文本到剪贴板的组合式函数
|
|
135
|
+
*
|
|
136
|
+
* @category Composables
|
|
137
|
+
* @param text 要复制的文本内容
|
|
138
|
+
* @returns 复制是否成功的Promise
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* // 复制简单文本
|
|
142
|
+
* const copyText = async () => {
|
|
143
|
+
* const success = await useCopyCode('Hello, World!')
|
|
144
|
+
* if (success) {
|
|
145
|
+
* console.log('复制成功')
|
|
146
|
+
* } else {
|
|
147
|
+
* console.log('复制失败')
|
|
148
|
+
* }
|
|
149
|
+
* }
|
|
150
|
+
*
|
|
151
|
+
* // 复制代码块
|
|
152
|
+
* const copyCodeBlock = async () => {
|
|
153
|
+
* const code = `
|
|
154
|
+
* function hello() {
|
|
155
|
+
* console.log('Hello, World!')
|
|
156
|
+
* }
|
|
157
|
+
* `
|
|
158
|
+
* const success = await useCopyCode(code)
|
|
159
|
+
* if (success) {
|
|
160
|
+
* // 显示复制成功提示
|
|
161
|
+
* showNotification('代码已复制到剪贴板')
|
|
162
|
+
* }
|
|
163
|
+
* }
|
|
164
|
+
*
|
|
165
|
+
* // 在点击事件中使用
|
|
166
|
+
* const handleCopy = () => {
|
|
167
|
+
* useCopyCode(document.getElementById('code').textContent)
|
|
168
|
+
* }
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
declare function useCopyCode(text: string): Promise<boolean>;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 树形数据结构操作类,提供树形数据的各种操作方法
|
|
175
|
+
*
|
|
176
|
+
* @category Data Structures
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* // 从扁平数组创建树形结构
|
|
180
|
+
* const flatList = [
|
|
181
|
+
* { id: '1', name: '根节点', pid: null },
|
|
182
|
+
* { id: '2', name: '子节点1', pid: '1' },
|
|
183
|
+
* { id: '3', name: '子节点2', pid: '1' },
|
|
184
|
+
* { id: '4', name: '孙节点', pid: '2' }
|
|
185
|
+
* ]
|
|
186
|
+
*
|
|
187
|
+
* const tree = Tree.fromList(flatList)
|
|
188
|
+
* console.log(tree) // 树形结构
|
|
189
|
+
*
|
|
190
|
+
* // 查找节点
|
|
191
|
+
* const found = Tree.find(tree, (node) => node.name === '子节点1')
|
|
192
|
+
*
|
|
193
|
+
* // 过滤节点
|
|
194
|
+
* const filtered = Tree.filter(tree, (node) => node.name.includes('子'))
|
|
195
|
+
*
|
|
196
|
+
* // 转换树形结构
|
|
197
|
+
* const transformed = Tree.transform(tree, (node) => ({
|
|
198
|
+
* ...node,
|
|
199
|
+
* displayName: `[${node.name}]`
|
|
200
|
+
* }))
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
declare class Tree {
|
|
204
|
+
private static dfsGenerator;
|
|
205
|
+
private static bfsGenerator;
|
|
206
|
+
private static selectStrategy;
|
|
207
|
+
/**
|
|
208
|
+
* 从扁平数组创建树形结构
|
|
209
|
+
*
|
|
210
|
+
* @category Data Structures
|
|
211
|
+
* @param list 扁平数组数据
|
|
212
|
+
* @param config 树形配置选项
|
|
213
|
+
* @returns 树形结构数组
|
|
214
|
+
* @example
|
|
215
|
+
* ```ts
|
|
216
|
+
* const flatData = [
|
|
217
|
+
* { id: '1', name: '部门1', parentId: null },
|
|
218
|
+
* { id: '2', name: '部门1-1', parentId: '1' },
|
|
219
|
+
* { id: '3', name: '部门1-2', parentId: '1' },
|
|
220
|
+
* { id: '4', name: '部门1-1-1', parentId: '2' }
|
|
221
|
+
* ]
|
|
222
|
+
*
|
|
223
|
+
* const tree = Tree.fromList(flatData, {
|
|
224
|
+
* id: 'id',
|
|
225
|
+
* pid: 'parentId',
|
|
226
|
+
* children: 'children'
|
|
227
|
+
* })
|
|
228
|
+
*
|
|
229
|
+
* console.log(tree) // 转换为树形结构
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
static fromList<T extends TreeNodeBase>(list: T[], config?: TreeConfigInput): TreeNode<T>[];
|
|
233
|
+
/**
|
|
234
|
+
* 将树形结构转换为扁平数组
|
|
235
|
+
*
|
|
236
|
+
* @category Data Structures
|
|
237
|
+
* @param tree 树形结构(单个节点或节点数组)
|
|
238
|
+
* @param config 树形配置选项
|
|
239
|
+
* @returns 扁平数组
|
|
240
|
+
* @example
|
|
241
|
+
* ```ts
|
|
242
|
+
* const tree = [
|
|
243
|
+
* {
|
|
244
|
+
* id: '1',
|
|
245
|
+
* name: '根节点',
|
|
246
|
+
* children: [
|
|
247
|
+
* { id: '2', name: '子节点1', children: [] },
|
|
248
|
+
* { id: '3', name: '子节点2', children: [] }
|
|
249
|
+
* ]
|
|
250
|
+
* }
|
|
251
|
+
* ]
|
|
252
|
+
*
|
|
253
|
+
* const flatList = Tree.toList(tree)
|
|
254
|
+
* console.log(flatList) // [{ id: '1', name: '根节点' }, { id: '2', name: '子节点1' }, ...]
|
|
255
|
+
* ```
|
|
256
|
+
*/
|
|
257
|
+
static toList<T extends TreeNodeBase>(tree: TreeNode<T> | TreeNode<T>[], config?: TreeConfigInput): T[];
|
|
258
|
+
static estimateSize<T extends TreeNodeBase>(tree: TreeNode<T> | TreeNode<T>[], config?: TreeConfigInput): number;
|
|
259
|
+
static find<T extends TreeNodeBase>(tree: TreeNode<T> | TreeNode<T>[], predicate: TreePredicate<T>, config?: TreeConfigInput): TreeNodeResult<T> | undefined;
|
|
260
|
+
static findAll<T extends TreeNodeBase>(tree: TreeNode<T> | TreeNode<T>[], predicate: TreePredicate<T>, config?: TreeConfigInput): TreeNodeResult<T>[];
|
|
261
|
+
static findById<T extends TreeNodeBase>(tree: TreeNode<T> | TreeNode<T>[], id: string, config?: TreeConfigInput): TreeNodeResult<T> | undefined;
|
|
262
|
+
static getStats<T extends TreeNodeBase>(tree: TreeNode<T> | TreeNode<T>[], config?: TreeConfigInput): TreeStats;
|
|
263
|
+
static filter<T extends TreeNodeBase>(tree: TreeNode<T> | TreeNode<T>[], predicate: TreePredicate<T>, config?: TreeConfigInput): TreeNode<T>[];
|
|
264
|
+
static transform<T extends TreeNodeBase, R extends TreeNodeBase>(tree: TreeNode<T> | TreeNode<T>[], transformer: TreeTransformer<T, R>, config?: TreeConfigInput): TreeNode<R>[];
|
|
265
|
+
static forEach<T extends TreeNodeBase>(tree: TreeNode<T> | TreeNode<T>[], visitor: TreeVisitor<T>, config?: TreeConfigInput): void;
|
|
266
|
+
static insertBefore<T extends TreeNodeBase>(tree: TreeNode<T>[], targetId: string, newNode: T, config?: TreeConfigInput): boolean;
|
|
267
|
+
static insertAfter<T extends TreeNodeBase>(tree: TreeNode<T>[], targetId: string, newNode: T, config?: TreeConfigInput): boolean;
|
|
268
|
+
static remove<T extends TreeNodeBase>(tree: TreeNode<T>[], targetId: string, config?: TreeConfigInput): TreeNode<T> | undefined;
|
|
269
|
+
static validate<T extends TreeNodeBase>(tree: TreeNode<T> | TreeNode<T>[], config?: TreeConfigInput): {
|
|
270
|
+
isValid: boolean;
|
|
271
|
+
errors: string[];
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* UnoCSS Flex布局预设,提供便捷的flex布局工具类
|
|
277
|
+
*
|
|
278
|
+
* @category Framework
|
|
279
|
+
* @returns UnoCSS预设配置对象
|
|
280
|
+
* @example
|
|
281
|
+
* ```ts
|
|
282
|
+
* // 在unocss.config.ts中使用
|
|
283
|
+
* import { presetFlex } from '@movk/core'
|
|
284
|
+
*
|
|
285
|
+
* export default defineConfig({
|
|
286
|
+
* presets: [
|
|
287
|
+
* presetFlex(),
|
|
288
|
+
* // 其他预设...
|
|
289
|
+
* ]
|
|
290
|
+
* })
|
|
291
|
+
*
|
|
292
|
+
* // 在HTML中使用生成的类名
|
|
293
|
+
* <div class="flex-row-center-center">居中的flex容器</div>
|
|
294
|
+
* <div class="flex-col-between-start">纵向分散对齐</div>
|
|
295
|
+
* <div class="flex-center">完全居中</div>
|
|
296
|
+
* <div class="flex-x-center">水平居中</div>
|
|
297
|
+
* <div class="flex-y-center">垂直居中</div>
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
declare function presetFlex(): {
|
|
301
|
+
name: string;
|
|
302
|
+
rules: ((RegExp | (([, d, j, a]: string[], { rawSelector }: {
|
|
303
|
+
rawSelector: string;
|
|
304
|
+
}) => Record<string, string>) | {
|
|
305
|
+
autocomplete: string;
|
|
306
|
+
})[] | (string | {
|
|
307
|
+
display: string;
|
|
308
|
+
'justify-content': string;
|
|
309
|
+
'align-items': string;
|
|
310
|
+
})[])[];
|
|
311
|
+
shortcuts: {
|
|
312
|
+
'flex-x-center': string;
|
|
313
|
+
'flex-y-center': string;
|
|
314
|
+
'inline-flex-x-center': string;
|
|
315
|
+
'inline-flex-y-center': string;
|
|
316
|
+
}[];
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
interface RuleContext {
|
|
320
|
+
rawSelector: string;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* UnoCSS 猫头鹰选择器预设,提供基于相邻兄弟选择器的间距和分隔符工具类
|
|
324
|
+
*
|
|
325
|
+
* @category Framework
|
|
326
|
+
* @returns UnoCSS预设配置对象
|
|
327
|
+
* @example
|
|
328
|
+
* ```ts
|
|
329
|
+
* // 在unocss.config.ts中使用
|
|
330
|
+
* import { presetOwl } from '@movk/core'
|
|
331
|
+
*
|
|
332
|
+
* export default defineConfig({
|
|
333
|
+
* presets: [
|
|
334
|
+
* presetOwl(),
|
|
335
|
+
* // 其他预设...
|
|
336
|
+
* ]
|
|
337
|
+
* })
|
|
338
|
+
*
|
|
339
|
+
* // 在HTML中使用生成的类名
|
|
340
|
+
* <div class="owl-y-4">
|
|
341
|
+
* <div>项目1</div>
|
|
342
|
+
* <div>项目2</div> <!-- 上边距 1rem -->
|
|
343
|
+
* <div>项目3</div> <!-- 上边距 1rem -->
|
|
344
|
+
* </div>
|
|
345
|
+
*
|
|
346
|
+
* <div class="owl-x-2">
|
|
347
|
+
* <span>按钮1</span>
|
|
348
|
+
* <span>按钮2</span> <!-- 左边距 0.5rem -->
|
|
349
|
+
* <span>按钮3</span> <!-- 左边距 0.5rem -->
|
|
350
|
+
* </div>
|
|
351
|
+
*
|
|
352
|
+
* <div class="owl-divide-gray-200">
|
|
353
|
+
* <div>列表项1</div>
|
|
354
|
+
* <div>列表项2</div> <!-- 上边框分隔线 -->
|
|
355
|
+
* <div>列表项3</div> <!-- 上边框分隔线 -->
|
|
356
|
+
* </div>
|
|
357
|
+
* ```
|
|
358
|
+
*/
|
|
359
|
+
declare function presetOwl(): {
|
|
360
|
+
name: string;
|
|
361
|
+
rules: (RegExp | (([, value]: string[], { rawSelector }: RuleContext) => string | undefined) | {
|
|
362
|
+
autocomplete: string;
|
|
363
|
+
})[][];
|
|
364
|
+
shortcuts: {
|
|
365
|
+
'owl-stack': string;
|
|
366
|
+
'owl-stack-tight': string;
|
|
367
|
+
'owl-stack-loose': string;
|
|
368
|
+
'owl-list': string;
|
|
369
|
+
'owl-list-tight': string;
|
|
370
|
+
'owl-nav': string;
|
|
371
|
+
'owl-card-stack': string;
|
|
372
|
+
}[];
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* 数组去重,返回去除重复元素后的新数组
|
|
377
|
+
*
|
|
378
|
+
* @category Array
|
|
379
|
+
* @param arr 待去重的数组
|
|
380
|
+
* @returns 去重后的新数组
|
|
381
|
+
* @example
|
|
382
|
+
* ```ts
|
|
383
|
+
* const numbers = [1, 2, 2, 3, 3, 4]
|
|
384
|
+
* const uniqueNumbers = unique(numbers)
|
|
385
|
+
* console.log(uniqueNumbers) // [1, 2, 3, 4]
|
|
386
|
+
*
|
|
387
|
+
* const strings = ['a', 'b', 'a', 'c']
|
|
388
|
+
* const uniqueStrings = unique(strings)
|
|
389
|
+
* console.log(uniqueStrings) // ['a', 'b', 'c']
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
declare function unique<T>(arr: T[]): T[];
|
|
393
|
+
/**
|
|
394
|
+
* 将数组分割成指定大小的块
|
|
395
|
+
*
|
|
396
|
+
* @category Array
|
|
397
|
+
* @param arr 待分割的数组
|
|
398
|
+
* @param size 每个块的大小
|
|
399
|
+
* @returns 分割后的二维数组
|
|
400
|
+
* @example
|
|
401
|
+
* ```ts
|
|
402
|
+
* const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
|
403
|
+
* const chunks = chunk(numbers, 3)
|
|
404
|
+
* console.log(chunks) // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
|
405
|
+
*
|
|
406
|
+
* const names = ['Alice', 'Bob', 'Charlie', 'David', 'Eve']
|
|
407
|
+
* const pairs = chunk(names, 2)
|
|
408
|
+
* console.log(pairs) // [['Alice', 'Bob'], ['Charlie', 'David'], ['Eve']]
|
|
409
|
+
* ```
|
|
410
|
+
*/
|
|
411
|
+
declare function chunk<T>(arr: T[], size: number): T[][];
|
|
412
|
+
/**
|
|
413
|
+
* 数组扁平化,将嵌套数组展平到指定深度
|
|
414
|
+
*
|
|
415
|
+
* @category Array
|
|
416
|
+
* @param arr 待扁平化的数组
|
|
417
|
+
* @param depth 扁平化深度,默认为1
|
|
418
|
+
* @returns 扁平化后的数组
|
|
419
|
+
* @example
|
|
420
|
+
* ```ts
|
|
421
|
+
* const nested = [1, [2, 3], [4, [5, 6]]]
|
|
422
|
+
* const flat1 = flatten(nested)
|
|
423
|
+
* console.log(flat1) // [1, 2, 3, 4, [5, 6]]
|
|
424
|
+
*
|
|
425
|
+
* const flat2 = flatten(nested, 2)
|
|
426
|
+
* console.log(flat2) // [1, 2, 3, 4, 5, 6]
|
|
427
|
+
* ```
|
|
428
|
+
*/
|
|
429
|
+
declare function flatten<T>(arr: T[], depth?: number): any[];
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* 防抖函数,在指定时间内多次触发只执行最后一次
|
|
433
|
+
*
|
|
434
|
+
* @category Async
|
|
435
|
+
* @param func 需要防抖的函数
|
|
436
|
+
* @param wait 防抖延迟时间(毫秒)
|
|
437
|
+
* @returns 防抖处理后的函数
|
|
438
|
+
* @example
|
|
439
|
+
* ```ts
|
|
440
|
+
* const debouncedSearch = debounce((query: string) => {
|
|
441
|
+
* console.log('搜索:', query)
|
|
442
|
+
* }, 300)
|
|
443
|
+
*
|
|
444
|
+
* // 连续调用,只有最后一次会执行
|
|
445
|
+
* debouncedSearch('a')
|
|
446
|
+
* debouncedSearch('ab')
|
|
447
|
+
* debouncedSearch('abc') // 只有这次会在300ms后执行
|
|
448
|
+
* ```
|
|
449
|
+
*/
|
|
450
|
+
declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void;
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* 延迟执行函数,返回一个在指定时间后resolve的Promise
|
|
454
|
+
*
|
|
455
|
+
* @category Async
|
|
456
|
+
* @param ms 延迟时间(毫秒)
|
|
457
|
+
* @returns 延迟Promise
|
|
458
|
+
* @example
|
|
459
|
+
* ```ts
|
|
460
|
+
* // 延迟1秒后继续执行
|
|
461
|
+
* await sleep(1000)
|
|
462
|
+
* console.log('1秒后执行')
|
|
463
|
+
*
|
|
464
|
+
* // 在异步函数中使用
|
|
465
|
+
* async function delayedOperation() {
|
|
466
|
+
* console.log('开始')
|
|
467
|
+
* await sleep(500)
|
|
468
|
+
* console.log('500ms后执行')
|
|
469
|
+
* }
|
|
470
|
+
* ```
|
|
471
|
+
*/
|
|
472
|
+
declare function sleep(ms: number): Promise<void>;
|
|
473
|
+
/**
|
|
474
|
+
* 可取消的延迟函数,返回Promise和取消函数
|
|
475
|
+
*
|
|
476
|
+
* @category Async
|
|
477
|
+
* @param ms 延迟时间(毫秒)
|
|
478
|
+
* @returns 包含Promise和取消函数的对象
|
|
479
|
+
* @example
|
|
480
|
+
* ```ts
|
|
481
|
+
* const { promise, cancel } = sleepWithCancel(5000)
|
|
482
|
+
*
|
|
483
|
+
* // 在另一个地方取消延迟
|
|
484
|
+
* setTimeout(() => {
|
|
485
|
+
* cancel() // 取消延迟
|
|
486
|
+
* }, 2000)
|
|
487
|
+
*
|
|
488
|
+
* try {
|
|
489
|
+
* await promise
|
|
490
|
+
* console.log('5秒后执行')
|
|
491
|
+
* } catch (error) {
|
|
492
|
+
* console.log('延迟被取消')
|
|
493
|
+
* }
|
|
494
|
+
* ```
|
|
495
|
+
*/
|
|
496
|
+
declare function sleepWithCancel(ms: number): {
|
|
497
|
+
promise: Promise<void>;
|
|
498
|
+
cancel: () => void;
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* 节流函数,在指定时间内多次触发只执行第一次
|
|
503
|
+
*
|
|
504
|
+
* @category Async
|
|
505
|
+
* @param func 需要节流的函数
|
|
506
|
+
* @param limit 节流时间间隔(毫秒)
|
|
507
|
+
* @returns 节流处理后的函数
|
|
508
|
+
* @example
|
|
509
|
+
* ```ts
|
|
510
|
+
* const throttledScroll = throttle((event: Event) => {
|
|
511
|
+
* console.log('滚动事件处理')
|
|
512
|
+
* }, 100)
|
|
513
|
+
*
|
|
514
|
+
* // 监听滚动事件,每100ms最多执行一次
|
|
515
|
+
* window.addEventListener('scroll', throttledScroll)
|
|
516
|
+
* ```
|
|
517
|
+
*/
|
|
518
|
+
declare function throttle<T extends (...args: any[]) => any>(func: T, limit: number): (...args: Parameters<T>) => void;
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* 将SVG字符串转换为PNG格式的Blob对象
|
|
522
|
+
*
|
|
523
|
+
* @category File
|
|
524
|
+
* @param svg SVG字符串
|
|
525
|
+
* @returns PNG格式的Blob对象
|
|
526
|
+
* @throws 当SVG无效或转换失败时抛出错误
|
|
527
|
+
* @example
|
|
528
|
+
* ```ts
|
|
529
|
+
* const svgString = '<svg width="100" height="100"><circle cx="50" cy="50" r="40" fill="red"/></svg>'
|
|
530
|
+
*
|
|
531
|
+
* try {
|
|
532
|
+
* const pngBlob = await convertSvgToPng(svgString)
|
|
533
|
+
* const url = URL.createObjectURL(pngBlob)
|
|
534
|
+
*
|
|
535
|
+
* // 用于下载或显示
|
|
536
|
+
* const img = document.createElement('img')
|
|
537
|
+
* img.src = url
|
|
538
|
+
* document.body.appendChild(img)
|
|
539
|
+
* } catch (error) {
|
|
540
|
+
* console.error('SVG转换失败:', error)
|
|
541
|
+
* }
|
|
542
|
+
* ```
|
|
543
|
+
*/
|
|
544
|
+
declare function convertSvgToPng(svg: string): Promise<Blob>;
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* 从响应头中提取文件名
|
|
548
|
+
*
|
|
549
|
+
* @category File
|
|
550
|
+
* @param headers 响应头对象
|
|
551
|
+
* @param fallbackName 默认文件名
|
|
552
|
+
* @returns 提取的文件名
|
|
553
|
+
* @example
|
|
554
|
+
* ```ts
|
|
555
|
+
* // 从响应头中提取文件名
|
|
556
|
+
* const headers = new Headers({
|
|
557
|
+
* 'content-disposition': 'attachment; filename="report.pdf"'
|
|
558
|
+
* })
|
|
559
|
+
* const filename = extractFilename(headers, 'download')
|
|
560
|
+
* console.log(filename) // 'report.pdf'
|
|
561
|
+
*
|
|
562
|
+
* // 处理编码的文件名
|
|
563
|
+
* const encodedHeaders = new Headers({
|
|
564
|
+
* 'content-disposition': 'attachment; filename*=UTF-8\'\'%E6%8A%A5%E5%91%8A.pdf'
|
|
565
|
+
* })
|
|
566
|
+
* const encodedFilename = extractFilename(encodedHeaders)
|
|
567
|
+
* console.log(encodedFilename) // '报告.pdf'
|
|
568
|
+
* ```
|
|
569
|
+
*/
|
|
570
|
+
declare function extractFilename(headers?: Headers, fallbackName?: string): string;
|
|
571
|
+
/**
|
|
572
|
+
* 触发浏览器下载文件
|
|
573
|
+
*
|
|
574
|
+
* @category File
|
|
575
|
+
* @param blob 文件数据
|
|
576
|
+
* @param filename 文件名
|
|
577
|
+
* @example
|
|
578
|
+
* ```ts
|
|
579
|
+
* // 下载文本文件
|
|
580
|
+
* const textBlob = new Blob(['Hello, World!'], { type: 'text/plain' })
|
|
581
|
+
* triggerDownload(textBlob, 'hello.txt')
|
|
582
|
+
*
|
|
583
|
+
* // 下载JSON数据
|
|
584
|
+
* const data = { name: 'John', age: 30 }
|
|
585
|
+
* const jsonBlob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
|
|
586
|
+
* triggerDownload(jsonBlob, 'data.json')
|
|
587
|
+
*
|
|
588
|
+
* // 下载图片
|
|
589
|
+
* const canvas = document.createElement('canvas')
|
|
590
|
+
* canvas.toBlob((blob) => {
|
|
591
|
+
* if (blob) {
|
|
592
|
+
* triggerDownload(blob, 'image.png')
|
|
593
|
+
* }
|
|
594
|
+
* })
|
|
595
|
+
* ```
|
|
596
|
+
*/
|
|
597
|
+
declare function triggerDownload(blob: Blob, filename: string): void;
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* 格式化文件大小,将字节数转换为可读的文件大小字符串
|
|
601
|
+
*
|
|
602
|
+
* @category File
|
|
603
|
+
* @param bytes 文件大小(字节)
|
|
604
|
+
* @returns 格式化后的文件大小字符串
|
|
605
|
+
* @example
|
|
606
|
+
* ```ts
|
|
607
|
+
* console.log(formatFileSize(1024)) // '1 KB'
|
|
608
|
+
* console.log(formatFileSize(1536)) // '1.5 KB'
|
|
609
|
+
* console.log(formatFileSize(1048576)) // '1 MB'
|
|
610
|
+
* console.log(formatFileSize(1073741824)) // '1 GB'
|
|
611
|
+
*
|
|
612
|
+
* // 处理边界情况
|
|
613
|
+
* console.log(formatFileSize(0)) // '0 Bytes'
|
|
614
|
+
* console.log(formatFileSize(-100)) // '0 Bytes'
|
|
615
|
+
* ```
|
|
616
|
+
*/
|
|
617
|
+
declare function formatFileSize(bytes: number): string;
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* 替换SVG文件中的currentColor为指定颜色
|
|
621
|
+
*
|
|
622
|
+
* @category File
|
|
623
|
+
* @param path SVG文件路径
|
|
624
|
+
* @param color 替换的颜色值,不提供则返回原始SVG
|
|
625
|
+
* @returns 处理后的SVG字符串
|
|
626
|
+
* @throws 当文件获取失败或SVG无效时抛出错误
|
|
627
|
+
* @example
|
|
628
|
+
* ```ts
|
|
629
|
+
* // 获取并替换SVG中的currentColor
|
|
630
|
+
* try {
|
|
631
|
+
* const svgContent = await replaceCurrentColor('/icons/star.svg', '#ff0000')
|
|
632
|
+
* const container = document.createElement('div')
|
|
633
|
+
* container.innerHTML = svgContent
|
|
634
|
+
* document.body.appendChild(container)
|
|
635
|
+
* } catch (error) {
|
|
636
|
+
* console.error('SVG处理失败:', error)
|
|
637
|
+
* }
|
|
638
|
+
*
|
|
639
|
+
* // 只获取SVG内容,不替换颜色
|
|
640
|
+
* const originalSvg = await replaceCurrentColor('/icons/star.svg')
|
|
641
|
+
* ```
|
|
642
|
+
*/
|
|
643
|
+
declare function replaceCurrentColor(path: string, color?: string): Promise<string>;
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* 将对象的键名转换为kebab-case格式
|
|
647
|
+
*
|
|
648
|
+
* @category Object
|
|
649
|
+
* @param obj 待转换的对象
|
|
650
|
+
* @param deep 是否深度转换嵌套对象,默认为false
|
|
651
|
+
* @returns 转换后的对象
|
|
652
|
+
* @example
|
|
653
|
+
* ```ts
|
|
654
|
+
* const obj = {
|
|
655
|
+
* firstName: 'John',
|
|
656
|
+
* lastName: 'Doe',
|
|
657
|
+
* userInfo: {
|
|
658
|
+
* birthDate: '1990-01-01',
|
|
659
|
+
* phoneNumber: '123-456-7890'
|
|
660
|
+
* }
|
|
661
|
+
* }
|
|
662
|
+
*
|
|
663
|
+
* const converted = convertToKebabCase(obj)
|
|
664
|
+
* console.log(converted)
|
|
665
|
+
* // {
|
|
666
|
+
* // 'first-name': 'John',
|
|
667
|
+
* // 'last-name': 'Doe',
|
|
668
|
+
* // 'user-info': { birthDate: '1990-01-01', phoneNumber: '123-456-7890' }
|
|
669
|
+
* // }
|
|
670
|
+
*
|
|
671
|
+
* const deepConverted = convertToKebabCase(obj, true)
|
|
672
|
+
* console.log(deepConverted)
|
|
673
|
+
* // {
|
|
674
|
+
* // 'first-name': 'John',
|
|
675
|
+
* // 'last-name': 'Doe',
|
|
676
|
+
* // 'user-info': { 'birth-date': '1990-01-01', 'phone-number': '123-456-7890' }
|
|
677
|
+
* // }
|
|
678
|
+
* ```
|
|
679
|
+
*/
|
|
680
|
+
declare function convertToKebabCase<T extends AnyObject>(obj: T, deep?: boolean): T;
|
|
681
|
+
|
|
682
|
+
/**
|
|
683
|
+
* 深度克隆对象,创建完全独立的副本
|
|
684
|
+
*
|
|
685
|
+
* @category Object
|
|
686
|
+
* @param obj 待克隆的对象
|
|
687
|
+
* @returns 深度克隆后的对象
|
|
688
|
+
* @example
|
|
689
|
+
* ```ts
|
|
690
|
+
* const original = {
|
|
691
|
+
* name: 'John',
|
|
692
|
+
* age: 30,
|
|
693
|
+
* address: {
|
|
694
|
+
* city: 'New York',
|
|
695
|
+
* zip: '10001'
|
|
696
|
+
* },
|
|
697
|
+
* hobbies: ['reading', 'coding']
|
|
698
|
+
* }
|
|
699
|
+
*
|
|
700
|
+
* const cloned = deepClone(original)
|
|
701
|
+
* cloned.address.city = 'Los Angeles'
|
|
702
|
+
* cloned.hobbies.push('gaming')
|
|
703
|
+
*
|
|
704
|
+
* console.log(original.address.city) // 'New York' (未改变)
|
|
705
|
+
* console.log(original.hobbies.length) // 2 (未改变)
|
|
706
|
+
* console.log(cloned.address.city) // 'Los Angeles'
|
|
707
|
+
* console.log(cloned.hobbies.length) // 3
|
|
708
|
+
* ```
|
|
709
|
+
*/
|
|
710
|
+
declare function deepClone<T>(obj: T): T;
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* 从对象中排除指定的键,返回新对象
|
|
714
|
+
*
|
|
715
|
+
* @category Object
|
|
716
|
+
* @param obj 源对象
|
|
717
|
+
* @param keys 要排除的键数组
|
|
718
|
+
* @returns 排除指定键后的新对象
|
|
719
|
+
* @example
|
|
720
|
+
* ```ts
|
|
721
|
+
* const user = {
|
|
722
|
+
* id: 1,
|
|
723
|
+
* name: 'John',
|
|
724
|
+
* password: 'secret',
|
|
725
|
+
* email: 'john@example.com'
|
|
726
|
+
* }
|
|
727
|
+
*
|
|
728
|
+
* const publicUser = omit(user, ['password'])
|
|
729
|
+
* console.log(publicUser) // { id: 1, name: 'John', email: 'john@example.com' }
|
|
730
|
+
*
|
|
731
|
+
* const basicInfo = omit(user, ['password', 'email'])
|
|
732
|
+
* console.log(basicInfo) // { id: 1, name: 'John' }
|
|
733
|
+
* ```
|
|
734
|
+
*/
|
|
735
|
+
declare function omit<T extends AnyObject, K extends keyof T>(obj: T, keys: K[]): OmitByKey<T, K>;
|
|
736
|
+
/**
|
|
737
|
+
* 从对象中排除值为undefined的键
|
|
738
|
+
*
|
|
739
|
+
* @category Object
|
|
740
|
+
* @param obj 源对象
|
|
741
|
+
* @returns 排除undefined值后的新对象
|
|
742
|
+
* @example
|
|
743
|
+
* ```ts
|
|
744
|
+
* const data = {
|
|
745
|
+
* name: 'John',
|
|
746
|
+
* age: undefined,
|
|
747
|
+
* city: 'New York',
|
|
748
|
+
* country: undefined
|
|
749
|
+
* }
|
|
750
|
+
*
|
|
751
|
+
* const cleaned = omitUndefined(data)
|
|
752
|
+
* console.log(cleaned) // { name: 'John', city: 'New York' }
|
|
753
|
+
*
|
|
754
|
+
* // 用于API请求前清理数据
|
|
755
|
+
* const requestData = omitUndefined({
|
|
756
|
+
* title: 'Post Title',
|
|
757
|
+
* content: 'Post content',
|
|
758
|
+
* tags: undefined,
|
|
759
|
+
* published: true
|
|
760
|
+
* })
|
|
761
|
+
* ```
|
|
762
|
+
*/
|
|
763
|
+
declare function omitUndefined<T extends AnyObject>(obj: T): Partial<T>;
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* 从对象中选择指定的键,返回新对象
|
|
767
|
+
*
|
|
768
|
+
* @category Object
|
|
769
|
+
* @param obj 源对象
|
|
770
|
+
* @param keys 要选择的键数组
|
|
771
|
+
* @returns 只包含指定键的新对象
|
|
772
|
+
* @example
|
|
773
|
+
* ```ts
|
|
774
|
+
* const user = {
|
|
775
|
+
* id: 1,
|
|
776
|
+
* name: 'John',
|
|
777
|
+
* email: 'john@example.com',
|
|
778
|
+
* password: 'secret',
|
|
779
|
+
* createdAt: '2023-01-01',
|
|
780
|
+
* updatedAt: '2023-01-15'
|
|
781
|
+
* }
|
|
782
|
+
*
|
|
783
|
+
* const publicInfo = pick(user, ['id', 'name', 'email'])
|
|
784
|
+
* console.log(publicInfo) // { id: 1, name: 'John', email: 'john@example.com' }
|
|
785
|
+
*
|
|
786
|
+
* const basicInfo = pick(user, ['id', 'name'])
|
|
787
|
+
* console.log(basicInfo) // { id: 1, name: 'John' }
|
|
788
|
+
* ```
|
|
789
|
+
*/
|
|
790
|
+
declare function pick<T extends AnyObject, K extends keyof T>(obj: T, keys: K[]): PickByKey<T, K>;
|
|
791
|
+
|
|
792
|
+
interface SeparateResult<T extends AnyObject, K extends keyof T> {
|
|
793
|
+
picked: PickByKey<T, K>;
|
|
794
|
+
omitted: OmitByKey<T, K>;
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* 将对象按指定键分离为两个对象
|
|
798
|
+
*
|
|
799
|
+
* @category Object
|
|
800
|
+
* @param obj 源对象
|
|
801
|
+
* @param keys 要分离的键数组
|
|
802
|
+
* @returns 包含picked和omitted两个对象的结果
|
|
803
|
+
* @example
|
|
804
|
+
* ```ts
|
|
805
|
+
* const user = {
|
|
806
|
+
* id: 1,
|
|
807
|
+
* name: 'John',
|
|
808
|
+
* email: 'john@example.com',
|
|
809
|
+
* password: 'secret',
|
|
810
|
+
* role: 'admin'
|
|
811
|
+
* }
|
|
812
|
+
*
|
|
813
|
+
* const { picked, omitted } = separate(user, ['id', 'name'])
|
|
814
|
+
* console.log(picked) // { id: 1, name: 'John' }
|
|
815
|
+
* console.log(omitted) // { email: 'john@example.com', password: 'secret', role: 'admin' }
|
|
816
|
+
*
|
|
817
|
+
* // 用于分离敏感信息
|
|
818
|
+
* const { picked: publicData, omitted: privateData } = separate(user, ['id', 'name', 'email'])
|
|
819
|
+
* ```
|
|
820
|
+
*/
|
|
821
|
+
declare function separate<T extends AnyObject, K extends keyof T>(obj: T, keys: K[]): SeparateResult<T, K>;
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* 将字符串首字母大写
|
|
825
|
+
*
|
|
826
|
+
* @category String
|
|
827
|
+
* @param str 待处理的字符串
|
|
828
|
+
* @returns 首字母大写的字符串
|
|
829
|
+
* @example
|
|
830
|
+
* ```ts
|
|
831
|
+
* console.log(capitalize('hello')) // 'Hello'
|
|
832
|
+
* console.log(capitalize('WORLD')) // 'WORLD'
|
|
833
|
+
* console.log(capitalize('')) // ''
|
|
834
|
+
* console.log(capitalize('a')) // 'A'
|
|
835
|
+
* ```
|
|
836
|
+
*/
|
|
837
|
+
declare function capitalize(str: string): string;
|
|
838
|
+
/**
|
|
839
|
+
* 将驼峰命名转换为kebab-case
|
|
840
|
+
*
|
|
841
|
+
* @category String
|
|
842
|
+
* @param str 驼峰命名的字符串
|
|
843
|
+
* @returns kebab-case格式的字符串
|
|
844
|
+
* @example
|
|
845
|
+
* ```ts
|
|
846
|
+
* console.log(camelToKebab('helloWorld')) // 'hello-world'
|
|
847
|
+
* console.log(camelToKebab('firstName')) // 'first-name'
|
|
848
|
+
* console.log(camelToKebab('XMLHttpRequest')) // 'x-m-l-http-request'
|
|
849
|
+
* console.log(camelToKebab('hello')) // 'hello'
|
|
850
|
+
* ```
|
|
851
|
+
*/
|
|
852
|
+
declare function camelToKebab(str: string): string;
|
|
853
|
+
/**
|
|
854
|
+
* 将kebab-case转换为驼峰命名
|
|
855
|
+
*
|
|
856
|
+
* @category String
|
|
857
|
+
* @param str kebab-case格式的字符串
|
|
858
|
+
* @returns 驼峰命名的字符串
|
|
859
|
+
* @example
|
|
860
|
+
* ```ts
|
|
861
|
+
* console.log(kebabToCamel('hello-world')) // 'helloWorld'
|
|
862
|
+
* console.log(kebabToCamel('first-name')) // 'firstName'
|
|
863
|
+
* console.log(kebabToCamel('background-color')) // 'backgroundColor'
|
|
864
|
+
* console.log(kebabToCamel('hello')) // 'hello'
|
|
865
|
+
* ```
|
|
866
|
+
*/
|
|
867
|
+
declare function kebabToCamel(str: string): string;
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* 生成字符串的简单哈希值
|
|
871
|
+
*
|
|
872
|
+
* @category Utilities
|
|
873
|
+
* @param str 待哈希的字符串
|
|
874
|
+
* @returns 32位哈希值转换为36进制字符串
|
|
875
|
+
* @example
|
|
876
|
+
* ```ts
|
|
877
|
+
* const hash1 = simpleHash('hello world')
|
|
878
|
+
* console.log(hash1) // 'nf5xd4'
|
|
879
|
+
*
|
|
880
|
+
* const hash2 = simpleHash('hello world')
|
|
881
|
+
* console.log(hash1 === hash2) // true,相同字符串产生相同哈希
|
|
882
|
+
*
|
|
883
|
+
* const hash3 = simpleHash('hello world!')
|
|
884
|
+
* console.log(hash1 === hash3) // false,不同字符串产生不同哈希
|
|
885
|
+
* ```
|
|
886
|
+
*/
|
|
887
|
+
declare function simpleHash(str: string): string;
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* 生成随机UUID字符串
|
|
891
|
+
*
|
|
892
|
+
* @category Utilities
|
|
893
|
+
* @returns 符合UUID v4格式的随机字符串
|
|
894
|
+
* @example
|
|
895
|
+
* ```ts
|
|
896
|
+
* const id1 = getRandomUUID()
|
|
897
|
+
* console.log(id1) // 'f47ac10b-58cc-4372-a567-0e02b2c3d479'
|
|
898
|
+
*
|
|
899
|
+
* const id2 = getRandomUUID()
|
|
900
|
+
* console.log(id2) // 'f47ac10b-58cc-4372-a567-0e02b2c3d480'
|
|
901
|
+
*
|
|
902
|
+
* // 用于生成唯一标识符
|
|
903
|
+
* const componentId = `component-${getRandomUUID()}`
|
|
904
|
+
* ```
|
|
905
|
+
*/
|
|
906
|
+
declare function getRandomUUID(): string;
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* 检查值是否为对象类型
|
|
910
|
+
*
|
|
911
|
+
* @category Validator
|
|
912
|
+
* @param value 待检查的值
|
|
913
|
+
* @returns 是否为对象类型
|
|
914
|
+
* @example
|
|
915
|
+
* ```ts
|
|
916
|
+
* console.log(isObject({})) // true
|
|
917
|
+
* console.log(isObject({ name: 'John' })) // true
|
|
918
|
+
* console.log(isObject([])) // false
|
|
919
|
+
* console.log(isObject(null)) // false
|
|
920
|
+
* console.log(isObject('string')) // false
|
|
921
|
+
* ```
|
|
922
|
+
*/
|
|
923
|
+
declare function isObject(value: any): value is AnyObject;
|
|
924
|
+
/**
|
|
925
|
+
* 检查值是否为数组类型
|
|
926
|
+
*
|
|
927
|
+
* @category Validator
|
|
928
|
+
* @param value 待检查的值
|
|
929
|
+
* @returns 是否为数组类型
|
|
930
|
+
* @example
|
|
931
|
+
* ```ts
|
|
932
|
+
* console.log(isArray([])) // true
|
|
933
|
+
* console.log(isArray([1, 2, 3])) // true
|
|
934
|
+
* console.log(isArray({})) // false
|
|
935
|
+
* console.log(isArray('string')) // false
|
|
936
|
+
* ```
|
|
937
|
+
*/
|
|
938
|
+
declare function isArray(value: any): value is any[];
|
|
939
|
+
/**
|
|
940
|
+
* 检查值是否为字符串类型
|
|
941
|
+
*
|
|
942
|
+
* @category Validator
|
|
943
|
+
* @param value 待检查的值
|
|
944
|
+
* @returns 是否为字符串类型
|
|
945
|
+
* @example
|
|
946
|
+
* ```ts
|
|
947
|
+
* console.log(isString('hello')) // true
|
|
948
|
+
* console.log(isString('')) // true
|
|
949
|
+
* console.log(isString(123)) // false
|
|
950
|
+
* console.log(isString(null)) // false
|
|
951
|
+
* ```
|
|
952
|
+
*/
|
|
953
|
+
declare function isString(value: any): value is string;
|
|
954
|
+
/**
|
|
955
|
+
* 检查值是否为有效数字类型
|
|
956
|
+
*
|
|
957
|
+
* @category Validator
|
|
958
|
+
* @param value 待检查的值
|
|
959
|
+
* @returns 是否为有效数字类型
|
|
960
|
+
* @example
|
|
961
|
+
* ```ts
|
|
962
|
+
* console.log(isNumber(123)) // true
|
|
963
|
+
* console.log(isNumber(0)) // true
|
|
964
|
+
* console.log(isNumber(NaN)) // false
|
|
965
|
+
* console.log(isNumber('123')) // false
|
|
966
|
+
* ```
|
|
967
|
+
*/
|
|
968
|
+
declare function isNumber(value: any): value is number;
|
|
969
|
+
/**
|
|
970
|
+
* 检查值是否为函数类型
|
|
971
|
+
*
|
|
972
|
+
* @category Validator
|
|
973
|
+
* @param value 待检查的值
|
|
974
|
+
* @returns 是否为函数类型
|
|
975
|
+
* @example
|
|
976
|
+
* ```ts
|
|
977
|
+
* console.log(isFunction(() => {})) // true
|
|
978
|
+
* console.log(isFunction(function() {})) // true
|
|
979
|
+
* console.log(isFunction(Math.max)) // true
|
|
980
|
+
* console.log(isFunction('string')) // false
|
|
981
|
+
* ```
|
|
982
|
+
*/
|
|
983
|
+
declare function isFunction(value: any): value is (...args: any[]) => any;
|
|
984
|
+
/**
|
|
985
|
+
* 检查值是否为空(null、undefined、空字符串、空数组、空对象)
|
|
986
|
+
*
|
|
987
|
+
* @category Validator
|
|
988
|
+
* @param value 待检查的值
|
|
989
|
+
* @returns 是否为空值
|
|
990
|
+
* @example
|
|
991
|
+
* ```ts
|
|
992
|
+
* console.log(isEmpty(null)) // true
|
|
993
|
+
* console.log(isEmpty(undefined)) // true
|
|
994
|
+
* console.log(isEmpty('')) // true
|
|
995
|
+
* console.log(isEmpty([])) // true
|
|
996
|
+
* console.log(isEmpty({})) // true
|
|
997
|
+
* console.log(isEmpty([1, 2])) // false
|
|
998
|
+
* console.log(isEmpty({ name: 'John' })) // false
|
|
999
|
+
* console.log(isEmpty('hello')) // false
|
|
1000
|
+
* ```
|
|
1001
|
+
*/
|
|
1002
|
+
declare function isEmpty(value: any): boolean;
|
|
1003
|
+
|
|
1004
|
+
export { StorageTypeSchema, Tree, TreeConfigSchema, TreeStatsSchema, camelToKebab, capitalize, chunk, convertSvgToPng, convertToKebabCase, createStorageConfigSchema, debounce, deepClone, extractFilename, flatten, formatFileSize, getRandomUUID, isArray, isEmpty, isFunction, isNumber, isObject, isString, kebabToCamel, omit, omitUndefined, pick, presetFlex, presetOwl, replaceCurrentColor, separate, simpleHash, sleep, sleepWithCancel, throttle, triggerDownload, unique, useAppStorage, useCopyCode };
|
|
1005
|
+
export type { AnyObject, AppStorageReturn, DeepPartial, FirstParam, FirstParameter, GetObjectField, MutableByKeys, OmitByKey, PartialByKeys, PickByKey, ReadonlyByKeys, RenameKeys, RequiredByKeys, StorageConfig, StorageConfigInput, StorageType, StringOrVNode, TreeConfig, TreeConfigInput, TreeNode, TreeNodeBase, TreeNodeResult, TreePredicate, TreeStats, TreeTransformer, TreeVisitor, UnionToIntersection };
|