Bogy
Bogy

Reputation: 21

Typescript generics - Type 'X' cannot be used to index type 'Y'

So, I am having issues with this part of the code (second line inside method remove causing the problem):

export abstract class Collection<T, K> {
    private data: Array<T> = [];

    add(item: T): void {
        this.data.push(item);
    }

    remove<J extends keyof K>(item: T, byKey: J): boolean {
        let index = this.data.findIndex((i: T) => i[byKey] === item[byKey]);
        this.data.splice(index, 1);
        return index != -1 ? true : false;
    }

    getAll(): Array<T> {
        return this.data;
    }
}

I am not sure what is the best way to explain the problem, here you can find repo

Upvotes: 0

Views: 607

Answers (1)

Eldar
Eldar

Reputation: 10790

I think i got you from the screenshot you share. You want to provide only properties that is not function. But you can't achieve it directly via generics. You also need help of the mapped types. What we need is a mapped typed that filters non functional properties. For that we need at least 2 mapped types one with filtering key and the other making a type with that filtered keys like below:

type FilteredKeys<T> = { [P in keyof T]: T[P] extends Function ? never : P }[keyof T];

type NonFunctionalProperties<T> = { [Q in FilteredKeys<T>]: T[Q] };

And then your function description will become like below :

 remove<J extends keyof NonFunctionalProperties<T>>(item: T, byKey: J): boolean {
        let index = this.data.findIndex((i: T) => i[byKey] === item[byKey]);
        this.data.splice(index, 1);
        return index != -1 ? true : false;
    }

Usage

collection.remove(c,"name") // ok
collection.remove(c,"get") // error

Playground

Upvotes: 1

Related Questions