Daniel
Daniel

Reputation: 3

Typescript inferring type fails

I'm using typescript version ^4.1.3 and have a REST API with albums and arts collections. Before I send the request response to web client, I remove the userId from collections.

Please see my Album and Arts interfaces from DynamoDB tables, and the utility method to remove the userId property from collection objects.

export interface Album {
    userId: string;
    albumId: string;
    creationDate: string;
    visibility: AlbumVisibility;
    title: string;
    description: string;
    coverUrl: string;
}

export interface Art {
    albumId: string;
    artId: string;
    sequenceNum: number;
    userId: string;
    creationDate: string;
    title: string;
    description: string;
    imgUrl: string;
}

export function rmUserIdFromArr(items: Album[] | Art[]) {
    return items.map((item: Album | Art) => {
        const { userId, ...newItem } = item;
        return newItem;
    });
}

But when I run the code in a collection of arts items, Typescript is complaining of:

const arts = rmUserIdFromArr(result.items).map((item) => ({
        ...item,
        imgUrl: getDownloadSignedUrl(getFsArtsFolder(item.albumId), item.artId),
    }));

Property 'artId' does not exist on type '{ albumId: string; creationDate: string; visibility: >AlbumVisibility; title: string; description: string; coverUrl: string; } | { albumId: string; >artId: string; sequenceNum: number; creationDate: string; title: string; description: string; >imgUrl: string; }'. Property 'artId' does not exist on type '{ albumId: string; creationDate: string; visibility: >AlbumVisibility; title: string; description: string; coverUrl: string; }'.ts(2339)

This is strange to me, because the artId exists in the Art interface type.

Am I missing something here? I know I can fix the issue setting the item from map function as item: any, but I was wondering if there`s a better way to fix this.

const arts = rmUserIdFromArr(result.items).map((item: any) => ({

Thank you very much, BR.

Upvotes: 0

Views: 47

Answers (1)

aleksxor
aleksxor

Reputation: 8340

I believe you should rewrite your function to something more generic:

function rmUserIdFromArr<T extends { userId: string }>(items: T[]): Omit<T, 'userId'>[] {
    return items.map((item) => {
        const { userId, ...newItem } = item;
        return newItem;
    });
}

playground link

Upvotes: 2

Related Questions