bendrucker/snakecase-keys

TypeScript: Exact key types

karlhorky opened this issue · 5 comments

As I mentioned earlier, it would be cool to get exact string literal key types, so you can get autocompletion and TypeScript errors on the keys that are accessed on the object.

Eg. look at this magic ✨ Note how the hover shows the correct key name student_id and the underlined red squiggly line highlights the typo in the key name.

Screen Shot 2021-04-30 at 16 44 25

This is possible with template literal types from TS 4.1 and key remapping in mapped types:

import originalSnakecaseKeys from 'snakecase-keys';

type CamelToSnakeCase<
  S extends string | number | symbol
> = S extends `${infer T}${infer U}`
  ? `${T extends Capitalize<T> ? '_' : ''}${Lowercase<T>}${CamelToSnakeCase<U>}`
  : S;

function snakecaseKeys<InputObject extends { [key: string]: any }>(
  inputObject: InputObject,
): {
  [K in keyof InputObject as CamelToSnakeCase<K>]: InputObject[K];
} {
  return originalSnakecaseKeys(inputObject);
}

@bendrucker would there be any interest in having exact string literals as keys in the TypeScript return types?

If so, we'd probably also need to think of the following cases:

  1. passing an array instead of an object
  2. recursive (with the deep option) - maybe this Stack Overflow would be helpful

Sure!

Hey, just an internet rando here, came here because I saw your comments on StackOverflow.

I managed to handle Arrays like this:

export type ServerRequest<T> = T extends Date
  ? string
  : T extends Array<any>
  ? Array<ServerRequest<T[number]>>
  : T extends object
  ? {
      [K in keyof T as CamelToSnakeCase<K & string>]: ServerRequest<T[K]>;
    }
  : T;

I also convert Dates to string because as the name suggests I convert app object to api objects.
Anyhoo, I couldn't comment on StackOverflow but maybe you find it useful or you have a better solution :)

Nice! Would you be able to try to make a PR by combining the code from both of our comments?

Sorry, I'm not using this library and I don't know the standards here 😁

Whoever ends up doing it, the PR could be similar to the PR here on camelcase-keys by @g-plane: sindresorhus/camelcase-keys#72 PR