1

I am create a small application in typescript, where I am using interfaces to create objects of specific types like the following UserProfile interface.

both the interface and the fulfill function are defined in user-profile.ts file.

export interface UserProfile  {

    readonly titel_id: number;
    readonly user_name: string;
    readonly email: string;
    readonly first_name: string;
    readonly last_name: string;
    readonly phone: string;
    readonly fax: string;

}

export function fulfill({  titel_id, user_name, email, first_name, last_name,  phone, fax }: any): UserProfile {
    return {

        titel_id,
        user_name,
        email,
        first_name,
        last_name,
        phone,
        fax
    }
}

I am calling this function from my UserMdoel's find function which contains all the fields of user table and fulfill function gives only those fields which are speficied in interface. But as you can see that I have to write the fields 3 times

once in interface, then in object destructring and then in return statement. It means if I later have to change the fields I have to change this on 3 places.

Is there a better way to solve this issue?

1
  • Casting your object to a specific type should suffice let profile: UserProfile = <UserProfile> object; Commented Apr 26, 2018 at 8:37

1 Answer 1

1

I updated my answer.

Interfaces do not survive the transpile to javascript. One thing you could do is to create an array with all the names and use this array to automatically copy over all fields.

You still have to maintain the fields in two places though.

export const USER_PROFILE_FIELDS: string[] = [
    'titel_id',
    'user_name',
    'email',
    'first_name',
    'last_name',
    'phone',
    'fax',
];
export interface UserProfile  {

    readonly titel_id: number;
    readonly user_name: string;
    readonly email: string;
    readonly first_name: string;
    readonly last_name: string;
    readonly phone: string;
    readonly fax: string;

}

export function fulfill(template: any): UserProfile {
    return <UserProfile>USER_PROFILE_FIELDS.reduce(
        (object, key) => object[key] = template[key],
        {}
    );
}

If you need this for multiple interfaces, you could create a higher order function which creates the fulfill function for you. Like that you don't need to manually create a fulfill function for each case. Here is an example:

// This function accepts the fields you want to use and returns your fulfill function
export function createFullfill<ResultingType>(fields: string[]) {
    return function(template: any) {
        return <ResultingType>fields.reduce(
            (object, key) => object[key] = template[key],
            {}    
        );
    } 
} 

// Fulfill function for UserProfile
export const fulfillUserProfile = createFullfill<UserProfile>(USER_PROFILE_FIELDS);
// Fulfill function for Project
export const fulfillProject = createFullfill<Project>(PROJECT_FIELDS);
Sign up to request clarification or add additional context in comments.

3 Comments

As I wrote that the Object I am providing all all the fields of a table. Which are much more than what I want to return.
Ah sorry, my bad, I missed that part.
I updated my answer, please have a look if this better serves your needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.