|
|
@@ -8,39 +8,56 @@ export * from 'axios';
|
|
|
|
|
|
const isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?(Z|[+-]\d{2}:\d{2})$/;
|
|
|
|
|
|
-function convertStringsToDatesRecursive(data: any, seen: Set<any>): any {
|
|
|
+// Utility type to decide the resulting type of every input object at compile time.
|
|
|
+type DeepDateConvert<T> = T extends string
|
|
|
+ ? (string extends T ? T : (RegExpMatchArray extends T ? T : Date)) // If T is exactly string it becomes Date
|
|
|
+ : T extends (infer U)[]
|
|
|
+ ? DeepDateConvert<U>[] // If T is an array, map its elements
|
|
|
+ : T extends object
|
|
|
+ ? { [K in keyof T]: DeepDateConvert<T[K]> } // If T is an object, map its properties
|
|
|
+ : T;
|
|
|
+
|
|
|
+function convertStringsToDatesRecursive<T>(data: T, seen: Set<any>): DeepDateConvert<T> {
|
|
|
if (typeof data !== 'object' || data === null) {
|
|
|
if (typeof data === 'string' && isoDateRegex.test(data)) {
|
|
|
- return new Date(data);
|
|
|
+ return new Date(data) as DeepDateConvert<T>;
|
|
|
}
|
|
|
- return data;
|
|
|
+ return data as DeepDateConvert<T>;
|
|
|
}
|
|
|
|
|
|
// Check for circular reference
|
|
|
if (seen.has(data)) {
|
|
|
- return data;
|
|
|
+ return data as DeepDateConvert<T>;
|
|
|
}
|
|
|
seen.add(data);
|
|
|
|
|
|
if (Array.isArray(data)) {
|
|
|
- return data.map(array => convertStringsToDatesRecursive(array, seen));
|
|
|
+ const resultArray = (data as any[]).map(array => convertStringsToDatesRecursive(array, seen));
|
|
|
+ return resultArray as DeepDateConvert<T>;
|
|
|
}
|
|
|
|
|
|
- for (const key of Object.keys(data)) {
|
|
|
- const value = data[key];
|
|
|
+ const newData: { [key: string]: any } = {};
|
|
|
+
|
|
|
+ for (const key of Object.keys(data as object)) {
|
|
|
+ const value = (data as any)[key];
|
|
|
+
|
|
|
if (typeof value === 'string' && isoDateRegex.test(value)) {
|
|
|
- data[key] = new Date(value);
|
|
|
+ newData[key] = new Date(value);
|
|
|
}
|
|
|
|
|
|
else if (typeof value === 'object' && value !== null) {
|
|
|
- data[key] = convertStringsToDatesRecursive(value, seen);
|
|
|
+ newData[key] = convertStringsToDatesRecursive(value, seen);
|
|
|
+ }
|
|
|
+
|
|
|
+ else {
|
|
|
+ newData[key] = value;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return data;
|
|
|
+ return newData as DeepDateConvert<T>;
|
|
|
}
|
|
|
|
|
|
-export function convertStringsToDates(data: any): any {
|
|
|
+export function convertStringsToDates<T>(data: T): DeepDateConvert<T> {
|
|
|
return convertStringsToDatesRecursive(data, new Set());
|
|
|
}
|
|
|
|