WIP: proper types for `objectToCamelCase`

This commit is contained in:
WofWca 2023-03-14 11:07:56 +04:00
parent cdf0690da6
commit 1eb4331a02
3 changed files with 50 additions and 3 deletions

View File

@ -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",

View File

@ -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'}

View File

@ -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') {