forked from vikunja/frontend
WIP: proper types for `objectToCamelCase`
This commit is contained in:
parent
cdf0690da6
commit
1eb4331a02
|
@ -124,6 +124,7 @@
|
|||
"eslint-plugin-vue": "9.9.0",
|
||||
"happy-dom": "8.9.0",
|
||||
"histoire": "0.15.8",
|
||||
"literal-case": "^1.0.0",
|
||||
"netlify-cli": "13.1.2",
|
||||
"postcss": "8.4.21",
|
||||
"postcss-easing-gradients": "3.0.1",
|
||||
|
|
|
@ -64,6 +64,7 @@ specifiers:
|
|||
histoire: 0.15.8
|
||||
is-touch-device: 1.0.1
|
||||
klona: 2.0.6
|
||||
literal-case: ^1.0.0
|
||||
lodash.debounce: 4.0.8
|
||||
marked: 4.2.12
|
||||
netlify-cli: 13.1.2
|
||||
|
@ -177,6 +178,7 @@ devDependencies:
|
|||
eslint-plugin-vue: 9.9.0_eslint@8.36.0
|
||||
happy-dom: 8.9.0
|
||||
histoire: 0.15.8_mbllq5flobsmlktljlyrk4fpme
|
||||
literal-case: 1.0.0
|
||||
netlify-cli: 13.1.2_@types+node@18.15.1
|
||||
postcss: 8.4.21
|
||||
postcss-easing-gradients: 3.0.1
|
||||
|
@ -10278,6 +10280,10 @@ packages:
|
|||
wrap-ansi: 7.0.0
|
||||
dev: true
|
||||
|
||||
/literal-case/1.0.0:
|
||||
resolution: {integrity: sha512-uJJFKXDMip5SraJINCO0as7guJkbMR1iVSkTpYIXaD6eaFuggskZyKcuAWYQJyJYoD39MWiAIPxTf/TystKq/g==}
|
||||
dev: true
|
||||
|
||||
/local-pkg/0.4.2:
|
||||
resolution: {integrity: sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==}
|
||||
engines: {node: '>=14'}
|
||||
|
|
|
@ -1,10 +1,50 @@
|
|||
import {camelCase} from 'camel-case'
|
||||
import {snakeCase} from 'snake-case'
|
||||
import {camelCase as camelCaseUntyped} from 'camel-case'
|
||||
import {snakeCase as snakeCaseUntyped} from 'snake-case'
|
||||
import type {
|
||||
camelCase as camelCaseTyped,
|
||||
snakeCase as snakeCaseTyped,
|
||||
CamelCase,
|
||||
SnakeCase,
|
||||
} from 'literal-case'
|
||||
|
||||
const camelCase = camelCaseUntyped as typeof camelCaseTyped
|
||||
const snakeCase = snakeCaseUntyped as typeof snakeCaseTyped
|
||||
|
||||
// type ObjectToCamelCase<T> = {
|
||||
// [P in keyof T as (P extends string
|
||||
// ? CamelCase<P>
|
||||
// : P
|
||||
// )]: T[P] extends (Record<string, unknown> | unknown[])
|
||||
// ? ObjectToCamelCase<T[P]>
|
||||
// : T[P]
|
||||
// }
|
||||
type NestedObjectsToCamelCase<
|
||||
// T extends (Record<string, unknown> | unknown[])
|
||||
T
|
||||
> = T extends unknown[]
|
||||
? {
|
||||
// Change array elements while keeping prototype properties the same.
|
||||
[P in keyof T]: P extends number
|
||||
? NestedObjectsToCamelCase<T[P]>
|
||||
: T[P]
|
||||
}
|
||||
// TODO what about class instances here? Methods would also get transformed. Is it right?
|
||||
// : T extends Record<string, any>
|
||||
: T extends Record<string, unknown>
|
||||
? {
|
||||
[P in keyof T as (P extends string
|
||||
? CamelCase<P>
|
||||
: P
|
||||
)]: NestedObjectsToCamelCase<T[P]>
|
||||
}
|
||||
: T
|
||||
|
||||
/**
|
||||
* Transforms field names to camel case.
|
||||
*/
|
||||
export function objectToCamelCase(object: Record<string, any>) {
|
||||
export function objectToCamelCase<T extends Record<string, any>>(
|
||||
object: T,
|
||||
): NestedObjectsToCamelCase<T> {
|
||||
|
||||
// When calling recursively, this can be called without being and object or array in which case we just return the value
|
||||
if (typeof object !== 'object') {
|
||||
|
|
Loading…
Reference in New Issue