@gateweb/react-utils 1.4.2 → 1.6.0
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/dist/cjs/index.d.ts +24 -1
- package/dist/cjs/index.js +33 -0
- package/dist/cjs/types.d.ts +84 -1
- package/dist/es/index.d.mts +24 -1
- package/dist/es/index.mjs +33 -1
- package/dist/es/types.d.mts +84 -1
- package/package.json +5 -5
package/dist/cjs/index.d.ts
CHANGED
|
@@ -358,7 +358,15 @@ type TValueOptions<T> = AtLeastOne<{
|
|
|
358
358
|
defaultValue?: T;
|
|
359
359
|
}>;
|
|
360
360
|
/**
|
|
361
|
+
* A hook to manage a value.
|
|
361
362
|
*
|
|
363
|
+
* @example
|
|
364
|
+
*
|
|
365
|
+
* ```tsx
|
|
366
|
+
* const MyComponent = ({ value }: { value?: number }) => {
|
|
367
|
+
* const [currentValue, setCurrentValue] = useValue({ value });
|
|
368
|
+
* };
|
|
369
|
+
* ```
|
|
362
370
|
*/
|
|
363
371
|
declare const useValue: <T>({ value, defaultValue }: TValueOptions<T>) => readonly [T, (newValue: T) => void];
|
|
364
372
|
|
|
@@ -415,6 +423,21 @@ declare const pick: <T extends object, K extends [...(keyof T)[]]>(object: T, ..
|
|
|
415
423
|
* const b = pickByValue(a, 1, 2); // { a: 1, b: 2 }
|
|
416
424
|
*/
|
|
417
425
|
declare const pickByValue: <T extends object, K extends any[]>(object: T, ...values: K) => Pick<T, { [K2 in keyof T]: T[K2] extends K[number] ? K2 : never; }[keyof T]>;
|
|
426
|
+
/**
|
|
427
|
+
* merge two objects deeply
|
|
428
|
+
*
|
|
429
|
+
* @param target - the target object
|
|
430
|
+
* @param source - the source object
|
|
431
|
+
*
|
|
432
|
+
* @example
|
|
433
|
+
*
|
|
434
|
+
* const obja = { a: { a1: { a11: 'value 1', a12: 'value 2' }, a2: 'value 3' }, b: 'value 4' };
|
|
435
|
+
* const objb = { a: { a1: { a13: 'value 5', a14: 'value 6' }, a3: 'value 7' }};
|
|
436
|
+
*
|
|
437
|
+
* const mergeResult = deepMerge(obja, objb); // { a: { a1: { a11: 'value 1', a12: 'value 2', a13: 'value 5', a14: 'value 6' }, a2: 'value 3', a3: 'value 7' }, b: 'value 4' }
|
|
438
|
+
*
|
|
439
|
+
*/
|
|
440
|
+
declare const deepMerge: <T extends object, U extends object>(target: T, source: U) => T & U;
|
|
418
441
|
|
|
419
442
|
/**
|
|
420
443
|
* debounce function
|
|
@@ -804,4 +827,4 @@ declare const getLocalStorage: <T>(key: string, deCode?: boolean) => T | undefin
|
|
|
804
827
|
*/
|
|
805
828
|
declare const setLocalStorage: (key: string, value: Record<string, any>, enCode?: boolean) => void;
|
|
806
829
|
|
|
807
|
-
export { type TCountdownActions, adToRocEra, camelCase2PascalCase, camelCase2SnakeCase, camelString2PascalString, camelString2SnakeString, createEnumLikeObject, debounce, downloadFile, extractEnumLikeObject, fakeApi, formatAmount, formatBytes, formatStarMask, generatePeriodArray, getCurrentPeriod, getLocalStorage, getMimeType, invariant, isChinese, isDateString, isDateTimeString, isEmail, isEnglish, isNonZeroStart, isNumber, isNumberAtLeastN, isNumberN, isNumberNM, isServer, isTWMobile, isTWPhone, isTimeString, isValidPassword, mergeRefs, omit, omitByValue, pascalCase2CamelCase, pascalCase2SnakeCase, pascalString2CamelString, pascalString2SnakeString, pick, pickByValue, rocEraToAd, setLocalStorage, snakeCase2CamelCase, snakeCase2PascalCase, snakeString2CamelString, snakeString2PascalString, throttle, useCountdown, useValue, validTaxId, validateDateString, validateFileType, wait };
|
|
830
|
+
export { type TCountdownActions, adToRocEra, camelCase2PascalCase, camelCase2SnakeCase, camelString2PascalString, camelString2SnakeString, createEnumLikeObject, debounce, deepMerge, downloadFile, extractEnumLikeObject, fakeApi, formatAmount, formatBytes, formatStarMask, generatePeriodArray, getCurrentPeriod, getLocalStorage, getMimeType, invariant, isChinese, isDateString, isDateTimeString, isEmail, isEnglish, isNonZeroStart, isNumber, isNumberAtLeastN, isNumberN, isNumberNM, isServer, isTWMobile, isTWPhone, isTimeString, isValidPassword, mergeRefs, omit, omitByValue, pascalCase2CamelCase, pascalCase2SnakeCase, pascalString2CamelString, pascalString2SnakeString, pick, pickByValue, rocEraToAd, setLocalStorage, snakeCase2CamelCase, snakeCase2PascalCase, snakeString2CamelString, snakeString2PascalString, throttle, useCountdown, useValue, validTaxId, validateDateString, validateFileType, wait };
|
package/dist/cjs/index.js
CHANGED
|
@@ -474,7 +474,15 @@ const transformObjectKey = (obj, transformFunName)=>{
|
|
|
474
474
|
};
|
|
475
475
|
|
|
476
476
|
/**
|
|
477
|
+
* A hook to manage a value.
|
|
477
478
|
*
|
|
479
|
+
* @example
|
|
480
|
+
*
|
|
481
|
+
* ```tsx
|
|
482
|
+
* const MyComponent = ({ value }: { value?: number }) => {
|
|
483
|
+
* const [currentValue, setCurrentValue] = useValue({ value });
|
|
484
|
+
* };
|
|
485
|
+
* ```
|
|
478
486
|
*/ const useValue = ({ value, defaultValue })=>{
|
|
479
487
|
if (value === undefined && defaultValue === undefined) {
|
|
480
488
|
throw new Error('Either `value` or `defaultValue` must be provided.');
|
|
@@ -594,6 +602,30 @@ message) {
|
|
|
594
602
|
}
|
|
595
603
|
return acc;
|
|
596
604
|
}, {});
|
|
605
|
+
const isObject = (value)=>value !== null && typeof value === 'object';
|
|
606
|
+
/**
|
|
607
|
+
* merge two objects deeply
|
|
608
|
+
*
|
|
609
|
+
* @param target - the target object
|
|
610
|
+
* @param source - the source object
|
|
611
|
+
*
|
|
612
|
+
* @example
|
|
613
|
+
*
|
|
614
|
+
* const obja = { a: { a1: { a11: 'value 1', a12: 'value 2' }, a2: 'value 3' }, b: 'value 4' };
|
|
615
|
+
* const objb = { a: { a1: { a13: 'value 5', a14: 'value 6' }, a3: 'value 7' }};
|
|
616
|
+
*
|
|
617
|
+
* const mergeResult = deepMerge(obja, objb); // { a: { a1: { a11: 'value 1', a12: 'value 2', a13: 'value 5', a14: 'value 6' }, a2: 'value 3', a3: 'value 7' }, b: 'value 4' }
|
|
618
|
+
*
|
|
619
|
+
*/ const deepMerge = (target, source)=>Object.entries(source).reduce((acc, [key, value])=>{
|
|
620
|
+
if (isObject(value)) {
|
|
621
|
+
acc[key] = key in target && isObject(target[key]) ? deepMerge(target[key], value) : value;
|
|
622
|
+
} else {
|
|
623
|
+
acc[key] = value;
|
|
624
|
+
}
|
|
625
|
+
return acc;
|
|
626
|
+
}, {
|
|
627
|
+
...target
|
|
628
|
+
});
|
|
597
629
|
|
|
598
630
|
/**
|
|
599
631
|
* debounce function
|
|
@@ -909,6 +941,7 @@ exports.camelString2PascalString = camelString2PascalString;
|
|
|
909
941
|
exports.camelString2SnakeString = camelString2SnakeString;
|
|
910
942
|
exports.createEnumLikeObject = createEnumLikeObject;
|
|
911
943
|
exports.debounce = debounce;
|
|
944
|
+
exports.deepMerge = deepMerge;
|
|
912
945
|
exports.extractEnumLikeObject = extractEnumLikeObject;
|
|
913
946
|
exports.fakeApi = fakeApi;
|
|
914
947
|
exports.formatAmount = formatAmount;
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -1,3 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A utility type that shifts the first argument of a function type `T` and returns the new function type.
|
|
3
|
+
*
|
|
4
|
+
* @template T - The function type to shift the first argument.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
*
|
|
8
|
+
* type Example = (arg1: string, arg2: number) => boolean;
|
|
9
|
+
* type ShiftedExample = ShiftArgs<Example>; // ShiftedExample is (arg2: number) => boolean;
|
|
10
|
+
*/
|
|
11
|
+
type ShiftArgs<T extends (...args: any) => any> = T extends (arg1: any, ...rest: infer P) => infer R ? (...args: P) => R : never;
|
|
12
|
+
/**
|
|
13
|
+
* A utility type that pops the last argument of a function type `T` and returns the new function type.
|
|
14
|
+
*
|
|
15
|
+
* @template T - The function type to pop the last argument.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
*
|
|
19
|
+
* type Example = (arg1: string, arg2: number) => boolean;
|
|
20
|
+
* type PoppedExample = PopArgs<Example>; // PoppedExample is (arg1: string) => boolean;
|
|
21
|
+
*/
|
|
22
|
+
type PopArgs<T extends (...args: any) => any> = T extends (...args: [...infer P, any]) => infer R ? (...args: P) => R : never;
|
|
23
|
+
/**
|
|
24
|
+
* A utility type that pushes a new argument of type `A` to the end of a function type `T` and returns the new function type.
|
|
25
|
+
*
|
|
26
|
+
* @template T - The function type to push the new argument.
|
|
27
|
+
* @template A - The new argument type to push.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
*
|
|
31
|
+
* type Example = (arg1: string, arg2: number) => boolean;
|
|
32
|
+
* type PushedExample = PushArgs<Example, boolean>; // PushedExample is (arg1: string, arg2: number, arg3: boolean) => boolean;
|
|
33
|
+
*/
|
|
34
|
+
type PushArgs<T extends (...args: any) => any, A> = T extends (...args: infer P) => infer R ? (...args: [...P, A]) => R : never;
|
|
35
|
+
/**
|
|
36
|
+
* A utility type that unshift a new argument of type `A` to the beginning of a function type `T` and returns the new function type.
|
|
37
|
+
*
|
|
38
|
+
* @template T - The function type to unshift the new argument.
|
|
39
|
+
* @template A - The new argument type to unshift.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
*
|
|
43
|
+
* type Example = (arg1: string, arg2: number) => boolean;
|
|
44
|
+
* type UnshiftExample = UnshiftArgs<Example, boolean>; // UnshiftExample is (arg3: boolean, arg1: string, arg2: number) => boolean;
|
|
45
|
+
*/
|
|
46
|
+
type UnshiftArgs<T extends (...args: any) => any, A> = T extends (...args: infer P) => infer R ? (...args: [A, ...P]) => R : never;
|
|
47
|
+
|
|
1
48
|
/**
|
|
2
49
|
* 從對象類型中提取特定屬性的值類型。
|
|
3
50
|
*
|
|
@@ -88,5 +135,41 @@ type OnlyOne<T> = {
|
|
|
88
135
|
[P in Exclude<keyof T, K>]?: never;
|
|
89
136
|
};
|
|
90
137
|
}[keyof T];
|
|
138
|
+
/**
|
|
139
|
+
* A utility type that makes all properties in the generic type `T` optional. Also, it makes all nested properties optional.
|
|
140
|
+
*
|
|
141
|
+
* @template T - The object type to make all properties optional.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
*
|
|
145
|
+
* type Example = { a: string; b: number };
|
|
146
|
+
* type ExamplePartial = DeepPartial<Example>;
|
|
147
|
+
*
|
|
148
|
+
* const obj: ExamplePartial = { a: 'hello' }; // OK
|
|
149
|
+
*
|
|
150
|
+
* type ExampleDeep = { a: { b: string; c: number } };
|
|
151
|
+
* type ExampleDeepPartial = DeepPartial<ExampleDeep>;
|
|
152
|
+
*
|
|
153
|
+
* const obj2: ExampleDeepPartial = { a: { b: 'world' } }; // OK
|
|
154
|
+
*/
|
|
155
|
+
type DeepPartial<T> = (T extends (infer U)[] ? DeepPartial<U>[] : {
|
|
156
|
+
[P in keyof T]?: DeepPartial<T[P]>;
|
|
157
|
+
}) | T;
|
|
158
|
+
/**
|
|
159
|
+
* 將 Obj 指定的 key 轉換成指定的型別
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
*
|
|
163
|
+
* ```ts
|
|
164
|
+
* type Obj = { a: string, b: number, c: boolean}
|
|
165
|
+
*
|
|
166
|
+
* type NewObj = TChangeKeyType<Obj, 'b', string> // { a: string, b: string, c: boolean }
|
|
167
|
+
*
|
|
168
|
+
* type NewObj2 = TChangeKeyType<Obj, 'b' | 'c', string> // { a: string, b: string, c: string }
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
type TChangeKeyType<T, K extends keyof T, V> = Omit<T, K> & {
|
|
172
|
+
[P in K]: V;
|
|
173
|
+
};
|
|
91
174
|
|
|
92
|
-
export type { AtLeastOne, Entries, MapToString, OnlyOne, TExtractValueType };
|
|
175
|
+
export type { AtLeastOne, DeepPartial, Entries, MapToString, OnlyOne, PopArgs, PushArgs, ShiftArgs, TChangeKeyType, TExtractValueType, UnshiftArgs };
|
package/dist/es/index.d.mts
CHANGED
|
@@ -358,7 +358,15 @@ type TValueOptions<T> = AtLeastOne<{
|
|
|
358
358
|
defaultValue?: T;
|
|
359
359
|
}>;
|
|
360
360
|
/**
|
|
361
|
+
* A hook to manage a value.
|
|
361
362
|
*
|
|
363
|
+
* @example
|
|
364
|
+
*
|
|
365
|
+
* ```tsx
|
|
366
|
+
* const MyComponent = ({ value }: { value?: number }) => {
|
|
367
|
+
* const [currentValue, setCurrentValue] = useValue({ value });
|
|
368
|
+
* };
|
|
369
|
+
* ```
|
|
362
370
|
*/
|
|
363
371
|
declare const useValue: <T>({ value, defaultValue }: TValueOptions<T>) => readonly [T, (newValue: T) => void];
|
|
364
372
|
|
|
@@ -415,6 +423,21 @@ declare const pick: <T extends object, K extends [...(keyof T)[]]>(object: T, ..
|
|
|
415
423
|
* const b = pickByValue(a, 1, 2); // { a: 1, b: 2 }
|
|
416
424
|
*/
|
|
417
425
|
declare const pickByValue: <T extends object, K extends any[]>(object: T, ...values: K) => Pick<T, { [K2 in keyof T]: T[K2] extends K[number] ? K2 : never; }[keyof T]>;
|
|
426
|
+
/**
|
|
427
|
+
* merge two objects deeply
|
|
428
|
+
*
|
|
429
|
+
* @param target - the target object
|
|
430
|
+
* @param source - the source object
|
|
431
|
+
*
|
|
432
|
+
* @example
|
|
433
|
+
*
|
|
434
|
+
* const obja = { a: { a1: { a11: 'value 1', a12: 'value 2' }, a2: 'value 3' }, b: 'value 4' };
|
|
435
|
+
* const objb = { a: { a1: { a13: 'value 5', a14: 'value 6' }, a3: 'value 7' }};
|
|
436
|
+
*
|
|
437
|
+
* const mergeResult = deepMerge(obja, objb); // { a: { a1: { a11: 'value 1', a12: 'value 2', a13: 'value 5', a14: 'value 6' }, a2: 'value 3', a3: 'value 7' }, b: 'value 4' }
|
|
438
|
+
*
|
|
439
|
+
*/
|
|
440
|
+
declare const deepMerge: <T extends object, U extends object>(target: T, source: U) => T & U;
|
|
418
441
|
|
|
419
442
|
/**
|
|
420
443
|
* debounce function
|
|
@@ -804,4 +827,4 @@ declare const getLocalStorage: <T>(key: string, deCode?: boolean) => T | undefin
|
|
|
804
827
|
*/
|
|
805
828
|
declare const setLocalStorage: (key: string, value: Record<string, any>, enCode?: boolean) => void;
|
|
806
829
|
|
|
807
|
-
export { type TCountdownActions, adToRocEra, camelCase2PascalCase, camelCase2SnakeCase, camelString2PascalString, camelString2SnakeString, createEnumLikeObject, debounce, downloadFile, extractEnumLikeObject, fakeApi, formatAmount, formatBytes, formatStarMask, generatePeriodArray, getCurrentPeriod, getLocalStorage, getMimeType, invariant, isChinese, isDateString, isDateTimeString, isEmail, isEnglish, isNonZeroStart, isNumber, isNumberAtLeastN, isNumberN, isNumberNM, isServer, isTWMobile, isTWPhone, isTimeString, isValidPassword, mergeRefs, omit, omitByValue, pascalCase2CamelCase, pascalCase2SnakeCase, pascalString2CamelString, pascalString2SnakeString, pick, pickByValue, rocEraToAd, setLocalStorage, snakeCase2CamelCase, snakeCase2PascalCase, snakeString2CamelString, snakeString2PascalString, throttle, useCountdown, useValue, validTaxId, validateDateString, validateFileType, wait };
|
|
830
|
+
export { type TCountdownActions, adToRocEra, camelCase2PascalCase, camelCase2SnakeCase, camelString2PascalString, camelString2SnakeString, createEnumLikeObject, debounce, deepMerge, downloadFile, extractEnumLikeObject, fakeApi, formatAmount, formatBytes, formatStarMask, generatePeriodArray, getCurrentPeriod, getLocalStorage, getMimeType, invariant, isChinese, isDateString, isDateTimeString, isEmail, isEnglish, isNonZeroStart, isNumber, isNumberAtLeastN, isNumberN, isNumberNM, isServer, isTWMobile, isTWPhone, isTimeString, isValidPassword, mergeRefs, omit, omitByValue, pascalCase2CamelCase, pascalCase2SnakeCase, pascalString2CamelString, pascalString2SnakeString, pick, pickByValue, rocEraToAd, setLocalStorage, snakeCase2CamelCase, snakeCase2PascalCase, snakeString2CamelString, snakeString2PascalString, throttle, useCountdown, useValue, validTaxId, validateDateString, validateFileType, wait };
|
package/dist/es/index.mjs
CHANGED
|
@@ -468,7 +468,15 @@ const transformObjectKey = (obj, transformFunName)=>{
|
|
|
468
468
|
};
|
|
469
469
|
|
|
470
470
|
/**
|
|
471
|
+
* A hook to manage a value.
|
|
471
472
|
*
|
|
473
|
+
* @example
|
|
474
|
+
*
|
|
475
|
+
* ```tsx
|
|
476
|
+
* const MyComponent = ({ value }: { value?: number }) => {
|
|
477
|
+
* const [currentValue, setCurrentValue] = useValue({ value });
|
|
478
|
+
* };
|
|
479
|
+
* ```
|
|
472
480
|
*/ const useValue = ({ value, defaultValue })=>{
|
|
473
481
|
if (value === undefined && defaultValue === undefined) {
|
|
474
482
|
throw new Error('Either `value` or `defaultValue` must be provided.');
|
|
@@ -588,6 +596,30 @@ message) {
|
|
|
588
596
|
}
|
|
589
597
|
return acc;
|
|
590
598
|
}, {});
|
|
599
|
+
const isObject = (value)=>value !== null && typeof value === 'object';
|
|
600
|
+
/**
|
|
601
|
+
* merge two objects deeply
|
|
602
|
+
*
|
|
603
|
+
* @param target - the target object
|
|
604
|
+
* @param source - the source object
|
|
605
|
+
*
|
|
606
|
+
* @example
|
|
607
|
+
*
|
|
608
|
+
* const obja = { a: { a1: { a11: 'value 1', a12: 'value 2' }, a2: 'value 3' }, b: 'value 4' };
|
|
609
|
+
* const objb = { a: { a1: { a13: 'value 5', a14: 'value 6' }, a3: 'value 7' }};
|
|
610
|
+
*
|
|
611
|
+
* const mergeResult = deepMerge(obja, objb); // { a: { a1: { a11: 'value 1', a12: 'value 2', a13: 'value 5', a14: 'value 6' }, a2: 'value 3', a3: 'value 7' }, b: 'value 4' }
|
|
612
|
+
*
|
|
613
|
+
*/ const deepMerge = (target, source)=>Object.entries(source).reduce((acc, [key, value])=>{
|
|
614
|
+
if (isObject(value)) {
|
|
615
|
+
acc[key] = key in target && isObject(target[key]) ? deepMerge(target[key], value) : value;
|
|
616
|
+
} else {
|
|
617
|
+
acc[key] = value;
|
|
618
|
+
}
|
|
619
|
+
return acc;
|
|
620
|
+
}, {
|
|
621
|
+
...target
|
|
622
|
+
});
|
|
591
623
|
|
|
592
624
|
/**
|
|
593
625
|
* debounce function
|
|
@@ -892,4 +924,4 @@ function mergeRefs(refs) {
|
|
|
892
924
|
*/ const wait = (ms)=>{
|
|
893
925
|
};
|
|
894
926
|
|
|
895
|
-
export { adToRocEra, camelCase2PascalCase, camelCase2SnakeCase, camelString2PascalString, camelString2SnakeString, createEnumLikeObject, debounce, extractEnumLikeObject, fakeApi, formatAmount, formatBytes, formatStarMask, generatePeriodArray, getCurrentPeriod, getMimeType, invariant, isChinese, isDateString, isDateTimeString, isEmail, isEnglish, isNonZeroStart, isNumber, isNumberAtLeastN, isNumberN, isNumberNM, isServer, isTWMobile, isTWPhone, isTimeString, isValidPassword, mergeRefs, omit, omitByValue, pascalCase2CamelCase, pascalCase2SnakeCase, pascalString2CamelString, pascalString2SnakeString, pick, pickByValue, rocEraToAd, snakeCase2CamelCase, snakeCase2PascalCase, snakeString2CamelString, snakeString2PascalString, throttle, useValue, validTaxId, validateDateString, validateFileType, wait };
|
|
927
|
+
export { adToRocEra, camelCase2PascalCase, camelCase2SnakeCase, camelString2PascalString, camelString2SnakeString, createEnumLikeObject, debounce, deepMerge, extractEnumLikeObject, fakeApi, formatAmount, formatBytes, formatStarMask, generatePeriodArray, getCurrentPeriod, getMimeType, invariant, isChinese, isDateString, isDateTimeString, isEmail, isEnglish, isNonZeroStart, isNumber, isNumberAtLeastN, isNumberN, isNumberNM, isServer, isTWMobile, isTWPhone, isTimeString, isValidPassword, mergeRefs, omit, omitByValue, pascalCase2CamelCase, pascalCase2SnakeCase, pascalString2CamelString, pascalString2SnakeString, pick, pickByValue, rocEraToAd, snakeCase2CamelCase, snakeCase2PascalCase, snakeString2CamelString, snakeString2PascalString, throttle, useValue, validTaxId, validateDateString, validateFileType, wait };
|
package/dist/es/types.d.mts
CHANGED
|
@@ -1,3 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A utility type that shifts the first argument of a function type `T` and returns the new function type.
|
|
3
|
+
*
|
|
4
|
+
* @template T - The function type to shift the first argument.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
*
|
|
8
|
+
* type Example = (arg1: string, arg2: number) => boolean;
|
|
9
|
+
* type ShiftedExample = ShiftArgs<Example>; // ShiftedExample is (arg2: number) => boolean;
|
|
10
|
+
*/
|
|
11
|
+
type ShiftArgs<T extends (...args: any) => any> = T extends (arg1: any, ...rest: infer P) => infer R ? (...args: P) => R : never;
|
|
12
|
+
/**
|
|
13
|
+
* A utility type that pops the last argument of a function type `T` and returns the new function type.
|
|
14
|
+
*
|
|
15
|
+
* @template T - The function type to pop the last argument.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
*
|
|
19
|
+
* type Example = (arg1: string, arg2: number) => boolean;
|
|
20
|
+
* type PoppedExample = PopArgs<Example>; // PoppedExample is (arg1: string) => boolean;
|
|
21
|
+
*/
|
|
22
|
+
type PopArgs<T extends (...args: any) => any> = T extends (...args: [...infer P, any]) => infer R ? (...args: P) => R : never;
|
|
23
|
+
/**
|
|
24
|
+
* A utility type that pushes a new argument of type `A` to the end of a function type `T` and returns the new function type.
|
|
25
|
+
*
|
|
26
|
+
* @template T - The function type to push the new argument.
|
|
27
|
+
* @template A - The new argument type to push.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
*
|
|
31
|
+
* type Example = (arg1: string, arg2: number) => boolean;
|
|
32
|
+
* type PushedExample = PushArgs<Example, boolean>; // PushedExample is (arg1: string, arg2: number, arg3: boolean) => boolean;
|
|
33
|
+
*/
|
|
34
|
+
type PushArgs<T extends (...args: any) => any, A> = T extends (...args: infer P) => infer R ? (...args: [...P, A]) => R : never;
|
|
35
|
+
/**
|
|
36
|
+
* A utility type that unshift a new argument of type `A` to the beginning of a function type `T` and returns the new function type.
|
|
37
|
+
*
|
|
38
|
+
* @template T - The function type to unshift the new argument.
|
|
39
|
+
* @template A - The new argument type to unshift.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
*
|
|
43
|
+
* type Example = (arg1: string, arg2: number) => boolean;
|
|
44
|
+
* type UnshiftExample = UnshiftArgs<Example, boolean>; // UnshiftExample is (arg3: boolean, arg1: string, arg2: number) => boolean;
|
|
45
|
+
*/
|
|
46
|
+
type UnshiftArgs<T extends (...args: any) => any, A> = T extends (...args: infer P) => infer R ? (...args: [A, ...P]) => R : never;
|
|
47
|
+
|
|
1
48
|
/**
|
|
2
49
|
* 從對象類型中提取特定屬性的值類型。
|
|
3
50
|
*
|
|
@@ -88,5 +135,41 @@ type OnlyOne<T> = {
|
|
|
88
135
|
[P in Exclude<keyof T, K>]?: never;
|
|
89
136
|
};
|
|
90
137
|
}[keyof T];
|
|
138
|
+
/**
|
|
139
|
+
* A utility type that makes all properties in the generic type `T` optional. Also, it makes all nested properties optional.
|
|
140
|
+
*
|
|
141
|
+
* @template T - The object type to make all properties optional.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
*
|
|
145
|
+
* type Example = { a: string; b: number };
|
|
146
|
+
* type ExamplePartial = DeepPartial<Example>;
|
|
147
|
+
*
|
|
148
|
+
* const obj: ExamplePartial = { a: 'hello' }; // OK
|
|
149
|
+
*
|
|
150
|
+
* type ExampleDeep = { a: { b: string; c: number } };
|
|
151
|
+
* type ExampleDeepPartial = DeepPartial<ExampleDeep>;
|
|
152
|
+
*
|
|
153
|
+
* const obj2: ExampleDeepPartial = { a: { b: 'world' } }; // OK
|
|
154
|
+
*/
|
|
155
|
+
type DeepPartial<T> = (T extends (infer U)[] ? DeepPartial<U>[] : {
|
|
156
|
+
[P in keyof T]?: DeepPartial<T[P]>;
|
|
157
|
+
}) | T;
|
|
158
|
+
/**
|
|
159
|
+
* 將 Obj 指定的 key 轉換成指定的型別
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
*
|
|
163
|
+
* ```ts
|
|
164
|
+
* type Obj = { a: string, b: number, c: boolean}
|
|
165
|
+
*
|
|
166
|
+
* type NewObj = TChangeKeyType<Obj, 'b', string> // { a: string, b: string, c: boolean }
|
|
167
|
+
*
|
|
168
|
+
* type NewObj2 = TChangeKeyType<Obj, 'b' | 'c', string> // { a: string, b: string, c: string }
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
type TChangeKeyType<T, K extends keyof T, V> = Omit<T, K> & {
|
|
172
|
+
[P in K]: V;
|
|
173
|
+
};
|
|
91
174
|
|
|
92
|
-
export type { AtLeastOne, Entries, MapToString, OnlyOne, TExtractValueType };
|
|
175
|
+
export type { AtLeastOne, DeepPartial, Entries, MapToString, OnlyOne, PopArgs, PushArgs, ShiftArgs, TChangeKeyType, TExtractValueType, UnshiftArgs };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gateweb/react-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "React Utils for GateWeb",
|
|
5
5
|
"homepage": "https://github.com/GatewebSolutions/react-utils",
|
|
6
6
|
"files": [
|
|
@@ -36,17 +36,17 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"dayjs": "^1.11.13",
|
|
39
|
-
"react": "^
|
|
40
|
-
"react-dom": "^
|
|
39
|
+
"react": "^19.0.0",
|
|
40
|
+
"react-dom": "^19.0.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@commitlint/cli": "^19.5.0",
|
|
44
44
|
"@commitlint/config-conventional": "^19.5.0",
|
|
45
45
|
"@gateweb/eslint-config-gateweb": "^1.0.6",
|
|
46
|
-
"@testing-library/react": "^16.0
|
|
46
|
+
"@testing-library/react": "^16.2.0",
|
|
47
47
|
"@types/jest": "^29.5.13",
|
|
48
48
|
"@types/node": "^22.7.7",
|
|
49
|
-
"@types/react": "^
|
|
49
|
+
"@types/react": "^19.0.8",
|
|
50
50
|
"@vitest/coverage-v8": "^2.1.4",
|
|
51
51
|
"@vitest/ui": "2.1.4",
|
|
52
52
|
"bunchee": "^5.6.1",
|