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:

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> {
    ...
}

Leave a Reply