Reputation: 1448
I walk through TS Handbook and I came to the mapped types. There is a code snippet to wrap object property into proxy.
type Proxy<T> = {
get(): T;
set(value: T): void;
}
type Proxify<T> = {
[P in keyof T]: Proxy<T[P]>;
}
function proxify<T>(o: T): Proxify<T> {
// ... wrap proxies ...
}
let proxyProps = proxify(props);
I'm trying to fill the gap in the proxify function with my implementation of it, and I get something like this:
function proxify<T>(t: T): Proxify<T> {
let result = <Proxify<T>>{};
for (const k in t) {
result[k] = { //(*) from that moment I lose strong typing
get: () => t[k],
set: (value) => t[k] = value
}
}
return result;
}
I can't control types inside the loop and everything must by of any type there. How to cope with that, assuming that my implementation is correct at all?
Upvotes: 2
Views: 1274
Reputation: 1541
My version of implementation is as below. I couldn't find a way to force type safety in get and set. It could be more elegant if there was some way to write properties like this get():PropType , set(value:PropType)
function proxify<T>(o: T): Proxify<T> {
const proxifyObj: Proxify<T> = <Proxify<T>>{};
Object.keys(o).map((key) => {
proxifyObj[key] = {
get() {
return o[key];
},
set(value) {
o[key] = value;
}
};
});
return proxifyObj;
}
Upvotes: 1
Reputation: 249696
The implementation seems ok. While creating the object there is some safety lost but you don't loose it all. The amount of typing you still get might actually surprise you
function proxify<T>(t: T): Proxify<T> {
let result = <Proxify<T>>{};
for (const k in t) { // k is of type Extract<keyof T, string> so it must be a key of T
// result[k] and t[k] both work because k is a key of both T and Proxify<T> but result['random'] would be invalid
result[k] = { // get/set fields are checked, so _get would be an error
// the return of get must be T[Extract<keyof T, string>] so ()=> 0 would be an error
get: () => t[k],
// value and t[k] must be T[Extract<keyof T, string>] so t[k] = '' would also be an error
set: (value) => t[k] = value
}
}
return result;
}
Upvotes: 5