Context:
I am working on an application, that generates filters for a GraphQL query dynamically.
To work with this generated filters, I am trying to create a Typescript type that resembles the allowed structure of these filters.
Issue:
The Typescript type I need, should allow every string as it’s key, with type A as its value. Only certain keys (in this case, “AND” and “OR”) should have a different type for their value.
Simplified Example:
The following example is simplified (while still complex enough):
The following filter Object should be allowed:
let filter = {
"fieldA": "2015-10-08",
"fieldB": "This is the search input string...",
OR: [
{"fieldC1": "deleted"},
{ AND: [
{"fieldD": "null"},
{"fieldE": "inactive"}
]}
],
}
After some search () and reading the docs I came up with this type:
type CustomTypeBase = {
[key: string]: string;
} & {
AND?: Array<{[key: string]: string} | CustomTypeBase>;
OR?: Array<{[key: string]: string} | CustomTypeBase>;
};
This does not work, sadly, as Typescript wants EVERY string-key (including “AND” and “OR) to hold a string value.
I tried to fix this problem with:
type CustomTypeWithOmit = Omit<{
[key: string]: string;
}, 'AND' | 'OR'> & {
AND?: Array<{[key: string]: string} | CustomTypeWithOmit>;
OR?: Array<{[key: string]: string} | CustomTypeWithOmit>;
};
But this does not work either, as the Omit utility type does not work on general types like string, but only works on specific types.
Question:
Is there any way to have a typescript type, that allows type A for all string keys and type B only for certain string keys?
TS Playground link:
Code on TS Playground