If I have a JSON schema saved in a file like f1040.json
with content:
[
{
name: "L1",
type: "String"
},
{
name: "C2",
type: "Boolean"
},
{
name: "L3",
type: "String"
},
...
]
And I want to generate a type that looks like:
type F1040 = {
L1: string;
C2: boolean;
L3: string;
...
}
How can I generate this without specifying each field manually (there are hundreds of them)? My first attempt at a solution isn't valid typescript (bc I'm providing more then one mapped type I think) but hopefully this invalid example clarifies what I'm trying to do:
import { f1040 } from "./f1040.json";
const bools = f1040.filter(e => e.type === "Boolean").map(e => name) as string[];
const strings = f1040.filter(e => e.type === "String").map(e => e.name) as string[];
export type F1040 = {
[key in (typeof bools)[number]]?: boolean;
[key in (typeof strings)[number]]?: string;
};
My incorrect solution was inspired by an answer to a similar but different question: TS create keys of new type from array of strings
Edit1: The solution doesn't need to be dynamic but if it's a build-time solution then it needs to play nice with rollup & the declarations bundler I'm using
Edit2: Another unsuccessful attempt, this time utilizing @sinclair/typebox:
import { Static, Type } from "@sinclair/typebox";
import { f1040 } from "./f1040.json";
const F1040 = Type.Object({
...f1040
.filter(e => e.type === "Boolean")
.map(e => e.name)
.reduce((res, f) => ({ ...res, [f]: Type.Boolean() }), {}),
...f1040
.filter(e => e.type === "String")
.map(e => e.name)
.reduce((res, f) => ({ ...res, [f]: Type.String() }), {}),
});
export type F1040 = Static<typeof F1040>;
const f1040Data = {
L1: true,
C2: "Yea",
} as F1040
The above attempt builds fine w/out any error.. which is too bad because the type assignments at the end are wrong. This should fail to build with a TypeError saying something like
Types of property 'L1' are incompatible. Type 'boolean' is not comparable to type 'string'.