Skip to content

Instantly share code, notes, and snippets.

@Tomas2D
Last active January 11, 2022 11:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tomas2D/939540879842d15087db07ffbef3f84c to your computer and use it in GitHub Desktop.
Save Tomas2D/939540879842d15087db07ffbef3f84c to your computer and use it in GitHub Desktop.
Type-safety for JSON translations (TypeScript)
import * as error from './cs/error.json';
/*
// Content of a "./cs/error.json" file
{
"general": {
"unexpected": "Došlo k neočekávané chybě."
},
"unauthorized": {
"token": "Váš přístup byl zamítnut, nevalidní token."
}
}
*/
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...0[]];
type PathsWithStringValue<T, D extends number = 10> = [D] extends [never]
? never
: T extends string
? []
: {
[K in Extract<keyof T, string>]: [K, ...PathsWithStringValue<T[K], Prev[D]>];
}[Extract<keyof T, string>];
type Join<T extends string[], D extends string> = T extends []
? never
: T extends [infer F]
? F
: T extends [infer F, ...infer R]
? F extends string
? `${F}${D}${Join<Extract<R, string[]>, D>}`
: never
: string;
type DottedStringPaths<T> = Join<PathsWithStringValue<T>, '.'>;
export type ErrorTranslationPath = `error.${DottedStringPaths<typeof error>}`;
let transErrorId: ErrorTranslationPath;
transErrorId = 'error.general.unexpected' // OK
transErrorId = 'error.general' // Error, `general` is not a string value
transErrorId = 'error.unauthorized' // Error, `unauthorized` is not a string value
transErrorId = 'error.unauthorized.token' // OK
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment