We use tons of configuration at work and this has come up time and time again. The biggest pain is when inevitably you need to "parameterize" your JSON files. The most common route I've seen is to turn your configs into templates e.g. Jinja and go from there. Welcome to hell.
My solution? Write a DSL with Typescript, and "compile" your configs down to JSON.
Define the structure of your configs as TS types. Write functions with free variables to work as templates, or define snippets as composable fragments. Writing the end result to a JSON file results in transparency (what you see is what you get) and compatibility.
jsonnet[1] might suit your use-case better, it was created to do exactly that.
the composition model strikes a good balance between data extensibility / language expressiveness / ease of use.
the generated json leads to easy-to-understand and portable data, and if you write jsonschemas from jsonnet, tools like json-schema-to-typescript [1] make it easy to import a consistent interface, and almost every language has a reasonably up-to-date validation library.