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",
|
"eslint-plugin-vue": "9.9.0",
|
||||||
"happy-dom": "8.9.0",
|
"happy-dom": "8.9.0",
|
||||||
"histoire": "0.15.8",
|
"histoire": "0.15.8",
|
||||||
|
"literal-case": "^1.0.0",
|
||||||
"netlify-cli": "13.1.2",
|
"netlify-cli": "13.1.2",
|
||||||
"postcss": "8.4.21",
|
"postcss": "8.4.21",
|
||||||
"postcss-easing-gradients": "3.0.1",
|
"postcss-easing-gradients": "3.0.1",
|
||||||
|
|
|
@ -64,6 +64,7 @@ specifiers:
|
||||||
histoire: 0.15.8
|
histoire: 0.15.8
|
||||||
is-touch-device: 1.0.1
|
is-touch-device: 1.0.1
|
||||||
klona: 2.0.6
|
klona: 2.0.6
|
||||||
|
literal-case: ^1.0.0
|
||||||
lodash.debounce: 4.0.8
|
lodash.debounce: 4.0.8
|
||||||
marked: 4.2.12
|
marked: 4.2.12
|
||||||
netlify-cli: 13.1.2
|
netlify-cli: 13.1.2
|
||||||
|
@ -177,6 +178,7 @@ devDependencies:
|
||||||
eslint-plugin-vue: 9.9.0_eslint@8.36.0
|
eslint-plugin-vue: 9.9.0_eslint@8.36.0
|
||||||
happy-dom: 8.9.0
|
happy-dom: 8.9.0
|
||||||
histoire: 0.15.8_mbllq5flobsmlktljlyrk4fpme
|
histoire: 0.15.8_mbllq5flobsmlktljlyrk4fpme
|
||||||
|
literal-case: 1.0.0
|
||||||
netlify-cli: 13.1.2_@types+node@18.15.1
|
netlify-cli: 13.1.2_@types+node@18.15.1
|
||||||
postcss: 8.4.21
|
postcss: 8.4.21
|
||||||
postcss-easing-gradients: 3.0.1
|
postcss-easing-gradients: 3.0.1
|
||||||
|
@ -10278,6 +10280,10 @@ packages:
|
||||||
wrap-ansi: 7.0.0
|
wrap-ansi: 7.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/literal-case/1.0.0:
|
||||||
|
resolution: {integrity: sha512-uJJFKXDMip5SraJINCO0as7guJkbMR1iVSkTpYIXaD6eaFuggskZyKcuAWYQJyJYoD39MWiAIPxTf/TystKq/g==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/local-pkg/0.4.2:
|
/local-pkg/0.4.2:
|
||||||
resolution: {integrity: sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==}
|
resolution: {integrity: sha512-mlERgSPrbxU3BP4qBqAvvwlgW4MTg78iwJdGGnv7kibKjWcJksrG3t6LB5lXI93wXRDvG4NpUgJFmTG4T6rdrg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
|
|
|
@ -1,10 +1,50 @@
|
||||||
import {camelCase} from 'camel-case'
|
import {camelCase as camelCaseUntyped} from 'camel-case'
|
||||||
import {snakeCase} from 'snake-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.
|
* 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
|
// 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') {
|
if (typeof object !== 'object') {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user