Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to define a type for an object with a required key and unknown optional additional keys?

I have a function that requires as an input an array of objects with a key "name" with an string value, but I want to use this helper function with any types of objects, having them more key-values pairs than that. How I should define this type? Thank you.

I have the following testable code as example:

interface UserInfo {
    id: number,
    name: string,
    productsIds: Array<number>,
    myProducts: number,
    competitors: number,
    isFavorite: boolean,
};

declare function getUsersInfo(): Array<UserInfo>;

function getAndSortUsersInfo(): Array<UserInfo> {
    const unsortedUserInfo = getUsersInfo();

    return sortByName(unsortedUserInfo);
}

interface ObjectWithName {
    [key: string]: any,
    name: string,
}

function sortByName(array: Array<ObjectWithName>): Array<ObjectWithName> {
    return array.sort(
        ({name: nameA}, {name: nameB}) => spaceship(nameA, nameB),
    );
}

function spaceship(elementA: any, elementB: any) {
    if (elementA < elementB) {
        return -1;
    }

    if (elementA > elementB) {
        return 1;
    }

    return 0;
}

But it throws me the following error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Type 'ObjectWithName[]' is not assignable to type 'UserInfo[]'.
  Type 'ObjectWithName' is missing the following properties from type 'UserInfo': id, productsIds, myProducts, competitors, isFavorite

>Solution :

your function sortByName needs to have a generic type parameter, otherwise the return type looses some information on the content of the array.

this is how the sort method is typed in typescript:

interface Array<T> {
    sort(compareFn?: (a: T, b: T) => number): Array<T>;
}

you can do this:

function sortByName<T extends { name: string}>(array: Array<T>): Array<T> {
    ...
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading