ค้นหาเว็บไซต์

วิธีการแปลงอินเทอร์เฟซเป็นประเภทแมปใน Typescript


พื้นหลัง

ในเอกสาร 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

คุณแค่ต้องสร้างอ็อบเจ็กต์ขึ้น 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;
}

บทความที่เกี่ยวข้อง