Typescript Generi c Литералы типов функций - PullRequest
0 голосов
/ 07 апреля 2020

Это работает, нет проблем:

type fun = (uid: string) => string 

const abc: fun = value => value

const efg = (callback:fun, value:string) =>callback(value)

console.log(efg(abc, "123"))

Но если мы go для generi c, это будет ошибка:

type fun = (uid: string) => string 

const abc: fun = value => value

const efg = <T>(callback:T, value:string) =>callback(value)

console.log(efg(abc, "123"))

Ошибка:

Это выражение не вызывается. Тип «unknown» не имеет сигнатур вызовов. (2349)

Демонстрация игровой площадки TypeScript

Я прочитал https://www.typescriptlang.org/docs/handbook/generics.html, но там говорится ничего о Generi c Литералы типов функций.

Мне нужно передать различные функции в качестве аргумента, поэтому мне это нужно.

Есть ли работа вокруг / взломать или есть на самом деле правильный способ сделать это?

Ответы [ 2 ]

2 голосов
/ 07 апреля 2020

Проблема в том, что тип T не ограничен, поэтому это может быть что угодно, вы можете передать туда number, string et c. Понятно, что вы не можете вызвать number, как если бы это была функция.

Как вы обрабатываете T в вашем коде, как если бы он был функцией с аргументом string, для этого необходимо дать такое ограничение. Рассмотрим:

const efg = <T extends (a: string) => any>(callback: T, value: string) => callback(value)

Выше T ограничен (ключевым словом extension) как функция, которая принимает string и может возвращать что угодно. Это означает, что все функции, такие как string->number, string-> boolean, string->object et c, в порядке.

Мы можем go продвинуться дальше и ограничить его (если вам нужно) и сказать, что наша функция только string->string, и именно такая интерфейс задается типом fun. Так что давайте расширим fun:

const efg = <T extends fun>(callback: T, value: string) => callback(value)

Детская площадка

0 голосов
/ 07 апреля 2020

Следующее, основанное на UnaryFunction rx js * может работать для вас.

Демонстрация TypeScript Playground:

interface Callable<T> {
    (source: T): T;
}

interface CallableInvoker<T> {
    // If the return type also needs to be T, replace any with T
    (callback: Callable<T>, value: T): any
}


function doubleNumber(value: number): number {
    return value * 2;
}

function doubleString(value: string): string {
    return value + value;
}

const efg: Callable<number> = doubleNumber; // Valid
const efg2: Callable<number> = doubleString; // Invalid, doubleString  must match the generic type

const efg3: CallableInvoker<number> = (doubleNumber, value) => doubleNumber(5);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...