Функции с обобщениями, используемыми в качестве параметров в других функциях - PullRequest
0 голосов
/ 28 февраля 2020

Допустим, я определяю тип CoolType следующим образом:

type CoolType<T> = {message: string, result: T} 

Затем я определяю тип CoolFunction для описания функции, которая возвращает CoolType:

type CoolFunction = <T>() => CoolType<T>

CoolFunction - это тип параметра, который ожидает вторая функция:

function superCoolFunction(coolFunction: CoolFunction) {
    return coolFunction()
}

В конце концов, после всех этих определений, я пытаюсь запустить некоторый код, подобный этому:

const res = superCoolFunction(<string>() => {
    return {message: 'I am the message', result: 'I am the result'}
})

, но , <string>() => { из приведенного выше кода я получаю сообщение об ошибке от компилятора, в котором говорится, что

'string' объявлено, но его значение никогда не читается. ts (6133) Аргумент типа '() => {сообщение: строка; результат: строка; } 'нельзя назначить параметру типа' CoolFunction '. Типы возврата подписи вызова '{message: string; результат: строка; } 'и' CoolType 'несовместимы. Типы «результата» несовместимы между этими типами. Тип 'string' не может быть назначен типу 'T'. «Строка» присваивается ограничению типа «T», но экземпляр «T» может быть создан с другим подтипом ограничения «{}». ts (2345)

Любая идея, что я делать неправильно? Вот stackblitz , который воспроизводит ошибку.

1 Ответ

2 голосов
/ 28 февраля 2020

У вас, похоже, дженерики не в тех местах. Я думаю, что вы хотите:

type CoolFunction<T> = () => CoolType<T>;

, то есть CoolFunction s также принимают обобщенный c тип. Тогда ваша функция более высокого порядка может распространять тип c:

function superCoolFunction<T>(coolFunction: CoolFunction<T>): CoolType<T> {
    return coolFunction();
}

. Теперь спецификатор типа c может быть выведен компилятором:

superCoolFunction(() => ({ message: 'foo', result: 123 }));
// function superCoolFunction<number>(coolFunction: CoolFunction<number>): CoolType<number>

или предоставлен явно:

superCoolFunction<string>(() => ({ message: 'foo', result: 'bar' }));
...