如何在 Typescript 中将接口转换为映射类型

How to convert interface to mapped type in Typescript

背景

在映射类型的 typescript documentation 中给出了以下示例:

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);

我不清楚如何编写代理函数。

我需要它做什么

我有以下类型

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]>;
};

并且我需要编写一个具有以下签名的函数

const wrap = <T>(o: T): WrappedInFormField<T> => {
    // ...What goes here?...
}

wrappedUser: WrappedInFormField<User> = wrap<User>(UserIJustGotFromApi);

我该怎么做?

您只需构建对象即可。 Typescript 不会提供创建映射类型的帮助,您只需像往常一样在 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;
}