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

7

背景

typescript 文档 的映射类型部分,给出了以下示例:

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

我不太清楚如何编写proxify函数。

我需要它的原因

我有以下类型:

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

我该如何做到这一点?

1个回答

4

你只需要构建对象。在创建映射类型时,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;
}

1
这是一个很好的答案,解决了我在文档中的误解 - 谢谢。我改了一些东西,使它与react-create-app Tslint配置兼容(const代替var,entries代替keys)。 - Christian Ravn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接