Typescript-generisk för att göra understreck-objekt till camel case
Säg att jag har ett gränssnitt som detta
interface Example {
first_name: string,
last_name: string,
home_town: string,
}
Jag letar efter en generisk som Camelize som kan ta Example och ändra alla nycklar så att de blir giltiga om de är kamelstil istället för understreck.
const e: Camelize<Example> = {
firstName: 'string',
lastName: 'string',
homeTown: 'string'
}
Är detta möjligt?
Svar #1
UPPDATERING för TypeScript 4.5:
Med introduktionen av borttagning av svansrekursion på villkorliga typer är det nu möjligt att skriva en version av Camelize som konverterar nycklar till camel case utan att lika lätt stöta på begränsningar för rekursionsdjup som tidigare:
Typen CamelizeString<T, C> använder C som en ackumulator för att lagra mellanresultat när strängen i snake case i T omvandlas till en sträng i camel case i C.
type CamelizeString<T extends PropertyKey, C extends string = ""> =
T extends string ? string extends T ? string :
T extends `${infer F}_${infer R}` ?
CamelizeString<Capitalize<R>, `${C}${F}`> : `${C}${T}` : T;
Resten av koden är densamma som versionen nedan.
Playground-länk till kod
TypeScript 4.1 introducerade template literal-typer och nyckelomkartläggning i mappade typer (se microsoft/TypeScript#40336), så du kan uppnå det på detta sätt:
type CamelizeString<T extends PropertyKey> =
T extends string ? string extends T ? string :
T extends `${infer F}_${infer R}` ? `${F}${Capitalize<CamelizeString<R>>}` : T : T;
type Camelize<T> = { [K in keyof T as CamelizeString<K>]: T[K] }
type CamelizeExample = Camelize<Example>;
/* type CamelizeExample = {
firstName: string;
lastName: string;
homeTown: string;
} */
const e: Camelize<Example> = {
firstName: 'string',
lastName: 'string',
homeTown: 'string'
}
Implementeringen av CamelizeString<T> hittar det första understreckstecknet ("_") i en sträng T, tar bort det och gör resten av strängen stor bokstav efter att rekursivt ha anropat CamelizeString på den resterande delen. Och Camelize<T> ommappar varje nyckel K i T till CamelizeString<K>.
Playground-länk till kod
Svar #2
För vad det är värt, stötte jag på några problem med typerna från @jcalz:s svar. Jag har hittat CamelCasedProperties och SnakeCasedProperties från https://github.com/sindresorhus/type-fest att fungera bra hittills.
