5

I have the following object:

const foo = {
  fieldAnt: "foo",
  fieldCab: "baz"
};

I'd like to automatically map that to a type with the keys made to uppercase and underscored:

type FIELDS = {
  FIELD_ANT: "fieldAnt",
  FIELD_CAB: "fieldCab" 
}

Is it possible using keyof or type mapping to programmatically achieve this with typescript?

Omair Vaiyani
  • 398
  • 3
  • 12
  • I don't think so... may I ask you why this would be useful? – Elias Mar 19 '20 at 18:45
  • Typescript only provides types, you're kinda asking that It actually affects and changes objects. – Elias Mar 19 '20 at 18:47
  • unfortunately you cannot do string manipulation using typescript types so while you could enforce the FIELDS values being equal to the keyof foo. You could not created the required uppercase, underscored keys themselves. – teddybeard Mar 19 '20 at 18:57
  • The idea is that I would run a function to actually create that object at runtime, but need the types present for static checks – Omair Vaiyani Mar 20 '20 at 09:01

1 Answers1

7

A little late :P but, with a little help I was able to do it:

const foo = {
  fieldAnt: "foo",
  fieldCab: "baz"
};

type CamelToSnakeCase<S extends string> =
  S extends `${infer T}${infer U}` ?
  `${T extends Capitalize<T> ? "_" : ""}${Lowercase<T>}${CamelToSnakeCase<U>}` :
  S

type Convert<T> = { [P in keyof T as Uppercase<CamelToSnakeCase<string & P>>]: P }

type Fields = Convert<typeof foo>
// type Fields = {
//  FIELD_ANT: "fieldAnt",
//  FIELD_CAB: "fieldCab" 
// }

TS Playground

Buszmen
  • 1,978
  • 18
  • 25