Typesafe navigation in JSON data structures for typescrpt.
Table of Contents
- Ever had a JSON data structure that is implemented in more than one file? Translation-files anyone?
- You wanted to access these values in a typesafe manner? I.e.: without resorting to string-keys?
- You want refactoring support from your IDE when renaming properties?
- You want compilation to fail if you mistyped a property name?
Read the examples in Usage to find out how!
Best shown by example:
import {TypesafeJsonPath} from '@honoluluhenk/typesafe-json-path';
const translationsRoot = {
FOO: {
BAR: {
BAZ: 'Baz was here!',
HELLO: 'Hello World',
}
}
};
const path = TypesafeJsonPath.init<typeof translationsRoot>();
// please note: this is not string but real property access!
const pathAsString = path.FOO.BAR.HELLO.$path.path;
// 'FOO.BAR.HELLO'
const value = path.FOO.BAR.HELLO.$path.get(translationsRoot);
console.log(value);
// 'Hello World'
The full power can be seen here: use a custom Resolver and go wild.
This example implements a translation service that is not access-by-string but fully typesafe!
import {type PathSegment, Resolver, TypesafeJsonPath} from '@honoluluhenk/typesafe-json-path';
const translationsRoot = {
FOO: {
BAR: {
BAZ: 'Baz was here!',
HELLO: 'Hello %s',
RUCKSACK: 'Rucksack',
},
},
};
// some other translation
const translationsDE = {
FOO: {
BAR: {
BAZ: 'Baz war hier!',
HELLO: 'Hallo %s',
},
},
};
// your custom path resolver
class Translator<T extends object> extends Resolver<unknown, T> {
constructor(
path: ReadonlyArray<PathSegment>,
private readonly myTranslateService: MyCustomTranslateService,
) {
super(path);
}
translate(...args: unknown[]): string {
// Delegate to some translation service.
return this.myTranslateService.translate(this.path, args);
}
}
// include all variants to have full refactoring support in your IDE
type TranslationType = typeof translationsRoot & typeof translationsDE;
// Now the real fun begins...
const translations = TypesafeJsonPath.init<TranslationType, Translator<any>>(
path => new Translator(
path,
new MyCustomTranslateService(navigator.languages[0], {en: translationsRoot, de: translationsDE}),
),
);
// again: this is not string but real property access in a typesafe and refactoring-friendly way!
const text = translations.FOO.BAR.HELLO.$path.translate('Welt');
// internally, myTranslateService.translate() was called with the path-string 'FOO.BAR.HELLO'.
console.log(text);
// Assuming the user language was some german (de) locale:
// 'Hallo Welt'
The implementation makes heavy use of the Proxy object.
As such, this lib can only be used if it is available.
This npm library is intended to be used in typescript projects where the
Just install the NPM package:
npm install @honoluluhenk/typesafe-json-path
See releases
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Run tests/linting (
npm run prepush
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the Lesser Gnu Public License 2.1 (LGPL-2.1) License. See LICENSE
for more information.
Christoph Linder - [email protected]
Project Link: https://github.com/HonoluluHenk/typesafe-json-path