I am looking for a way to correctly express my data model with tyepscript definitions. So far I have the following:
type Data = Record<string, string>;
interface DataContainer<D extends Data> {
id: string;
data: D;
}
interface Context {
dataContainers: DataContainer<any>[];
}
A Context stores a set of DataContainers, where each DataContainer is generic over a specific data structure D. Now what I want to express is that each of those data structures D should follow a universal type Data. I.e. consisting of arbitrary but fixed <string, string> pairs.
I really could not find a proper solution for that, the best thing I found was DataContainer<D extends Data>. Do you think that's a good approach?
At least the following gives my a linting error as desired:
interface MyData extends Data {
x: "1",
y: 2, // Lint error, because not string. (As I want it)
}
So I conclude that when writing <D extends Data> it would also not be allowed for D to have an entry like y: 2, correct?
Now a real problem for me is that the following does not give me a linting error:
const myContext: Context = {
dataContainers: [
{
id: "123",
data: {
x: 1, // This should be marked by the linter
y: "2",
z: {a: 1}, // This also
}
}
]
}
I am looking for a way to model my definitions such that a linter would mark this as invalid, because there exists no D such that the above would be a valid Context. Is that possible? Thanks for your help!