Как применить общий тип для внутренней функции в машинописном тексте

Я пытаюсь написать общую функцию в машинописном тексте, которая в основном выполняет фильтр из массива. Вот эквивалентная функция в javascript

const filterByProp = function (prop, value) {
    return function (item) {
        return item[prop] === value;
    }
}

const result = people.filter(filterByProp('age', 3))

Приведенный выше код работает нормально, то же самое нужно преобразовать в машинописный текст.

Ниже функция typescript работает нормально. но внутренняя функция не имеет никакого типа :(

Версия 2:

const filterByProp2 = function <T, K extends keyof T>(prop: K, value: T[K]) {
    return function (item): boolean {
        return item[prop] === value;
    }
}

Версия 3:

Ниже приведен код, который не работает должным образом. После применения типа для внутренней функции.

const filterByProp3 = function <T, K extends keyof T>(prop: K, value: T[K]) {
    return function <T>(item: T): boolean {
        return item[prop] === value;
    }
}

Применение:

const result3 = people.filter(filterByProp3<IUser, 'age'>('age', 3)) // Not sure how to pass for inner func <IUser>

Я получил ошибку, как

[ts] Type 'K' cannot be used to index type 'T'.
[ts] This condition will always return 'false' since the types 'T[K]' and 'T[K]' have no overlap.

Может кто-нибудь помочь, как это решить?

Версия 4: это работает, но я предпочитаю решить проблему версии 3.

function filterByProp4<T, K extends keyof T>(
    prop: K,
    entities: T[],
    value: T[K]
) {
    return entities.filter(e => e[prop] === value);
}

person Raja Jaganathan    schedule 18.08.2018    source источник


Ответы (1)


Вам просто нужно указать параметр того же типа во внутренней функции. Typescript выведет T на основе ожидаемого возвращаемого типа внешней функции, когда вы используете его в качестве аргумента для фильтрации, поэтому не требуются явные параметры типа:

interface Person { 
    age: number
}
const filterByProp = function <T, K extends keyof T>(prop: K, value: T[K]) {
    return function (item: T): boolean {
        return item[prop] === value;
    }
}
const people: Person[] = [{ age: 3}, { age: 2}];
const result = people.filter(filterByProp('age', 3))
people.filter(filterByProp('age', "3")) //error
people.filter(filterByProp('Age', 3)) //error
person Titian Cernicova-Dragomir    schedule 18.08.2018