type KeyValueWrapperTypeObject = {
[key: string]: Wrapper<unknown>,
}
type KeyValueUnknownTypeObject = {
[key: string]: unknown,
}
type MyDeterminedTypedObject = {
key1: Wrapper<string>,
key2: Wrapper<number>,
key3: Wrapper<{
nestedKey: boolean,
}>
}
type ConvertValueTypesOfMappedTypeToSpecifiedType<MappedType, SpecifiedType> = {
[K in keyof MappedType]: SpecifiedType;
};
class Wrapper<T> {
#t: T
constructor(t: T) {
this.#t = t
}
reveal(): T {
return this.#t
}
}
function makeKeyValueWrapperObjectFromJson<S extends KeyValueWrapperTypeObject>(json: string): S {
const parsedJson = JSON.parse(json);
const result: any = {};
for (const key in parsedJson) {
if (Object.prototype.hasOwnProperty.call(parsedJson, key)) {
result[key] = new Wrapper(parsedJson[key]);
}
}
return result;
}
const jsonString = '{"key1": "value1", "key2": "123", "key3": {"nestedKey": true}}';
const keyValueWrapperObject = makeKeyValueWrapperObjectFromJson<MyDeterminedTypedObject>(jsonString);
console.log(keyValueWrapperObject.key1.reveal());
console.log(keyValueWrapperObject.key2.reveal()); // how to type check this?
console.log(keyValueWrapperObject.key3.reveal().nestedKey);
I am trying to wrap all the values of an arbitrary object with Wrapper<T>.
The function makeKeyValueWrapperObjectFromJson, first parses a JSON string, then given that parsed TypeScript object, it looks through all its values, construct a new Wrapper<T> and setting it as the value corresponding to the key of the object as typed by MyDeterminedTypedObject.
key2 is supposed to be of type number but the JSON string has it as "123" which is parsed as string.
Is there anyway to write makeKeyValueWrapperObjectFromJson, such that it is able to create arbitrary instances of any tips just by 'inspecting' the type argument MyDeterminedTypedObject passed into the type parameter of the function?