Reputation: 187
In the typescript documentation for mapped types the following example is given:
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);
It is unclear to me how I would write the proxify function.
I have the following types
interface User extends BaseRecord {
readonly 'id': number;
readonly 'name'?: string;
}
interface FormField<T> {
readonly value: T;
readonly edited: boolean;
}
type WrappedInFormField<T> = {
[P in keyof T]: FormField<T[P]>;
};
And I need to write a function with the following signature
const wrap = <T>(o: T): WrappedInFormField<T> => {
// ...What goes here?...
}
wrappedUser: WrappedInFormField<User> = wrap<User>(UserIJustGotFromApi);
How can I do that?
Upvotes: 7
Views: 14028
Reputation: 250376
You need to just build up the object. Typescript will offer no help in creating mapped types, you just build them up as you normally would in Javascript.
const wrap = <T>(o: T): WrappedInFormField<T> => {
// Create an empty object that we will add the properties to, assert it will be a WrappedInFormField<T> once we are done with it
let result = {} as WrappedInFormField<T>;
// Get all the keys of the original object
for(var key in Object.keys(o)) {
// Create something compatible with FormField
// You could instantiate a class, but you will not have access to the type of each property,
// you could use any instead (for example if FormField<T> is a class you could just call new FormField<any> since types are erased it will not really matter)
result[key] = {
value: o[key],
edited: false
};
}
// return the result
return result;
}
Upvotes: 4