I encountered a runtime TypeError that I believe should have been caught during compile time with TypeScript. Here is the code snippet:
type MyData = Record<string, Record<string, string>>;
function retrieveData(): MyData {
return {
sample: {
info: "value",
}
};
}
const data = retrieveData();
const value = data.Section.Value; // TypeError: data.Section is undefined
In the above scenario, since MyObject
is an object where keys are strings, TypeScript assumes that any string can be used as a key with the corresponding value being Record<string, string>
. However, in reality, there might be a limited number of keys on an object unless explicitly defined using a getter to return a string for any other given key.
To address this issue, I attempted utilizing
Partial<Record>
. Although this type resolves the previous bug, it presents challenges when iterating over the object:
type MyData = Partial>;
function retrieveData(): MyData {
return {
sample: {
info: "value",
}
};
}
const data = retrieveData();
Object.values(data).filter(val => val.Value); // val: Object is possibly undefined
The error mentioned above cannot occur during runtime because if a property exists on data
, it will definitely be of type Record<string, string>
. Unfortunately, I am uncertain how to convey this information using the type system.
Hence, my query is: How can I define a type for an object that
- consists solely of string keys,
- does not have defined properties for all strings,
- and if a property is defined, the corresponding value is guaranteed to be
Record<string, string>
?
Edit: While specifying all keys in the type (like Record<"keya"|"keyb", string>
) is feasible, it does not align with my requirement as I do not know all the keys in advance. What I seek is a type named PartialRecord
where if data: PartialRecord<string, T>
, then data.SOMEKEY
has the type T | undefined
(since the key SOMEKEY
may not exist returning undefined
) but Object.values(data)
should yield T[]
, signifying that Object.values
only returns existing values of type T
.