Как определить тип generi c для результата обратного вызова / функции ИЛИ результата выражения - PullRequest
0 голосов
/ 01 марта 2020

Моя проблема в том, что моя функция dbg() принимает либо анонимную функцию (например: dbg(() => 4 + 1)), либо выражение (например: dbg(4 + 1)). В любом случае он регистрирует результат в удобном формате и возвращает результат. Предпочтительна версия анонимной функции (вы можете видеть мой пакет , если вам интересно, почему).

Я успешно использовал обобщенные коды TypeScript, чтобы разрешить результат анонимной функции тип, чтобы пройти. Так что я мог бы использовать его встроенным и получить правильную типизацию, например так:

// weight is typed as a number instead of any or unknown
const weight = dbg(() => mass * gravity); // logs '[/src/physics.js:12] mass * gravity = 58.12'

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

Вот подпись метода:

function dbg<T>(input: CallbackOrExpression<T>): ResultOfCallbackOrExpression<T>

А вот типы:

type Callback<T> = () => T; // a function with no params
type Expression<T> = T extends Function ? never : T; // anything that is not a function
type CallbackOrExpression<T> = Callback<T> | Expression<T>;
type ResultOfCallbackOrExpression<T> = ReturnType<Callback<T>> | T; // always evaluates to T, but more explicit

Я думаю, что мой проблема в том, что CallbackOrExpression (который является типом параметра) никогда не использует тип Expression generi c, только Callback. Доказательством этого является то, что выражение само по себе имеет буквальный тип, например так:

// has a type of "hello" (yes, the literal string!)
const something = dbg("hello"); // logs '[/package/hello.ts:1] hello'

// has a type of 86 (yes, the literal number!)
const somethingElse = dbg(88 - 2); // logs '[/package/hello.ts:3] 86'

Это пакет с открытым исходным кодом, который я создал для более простой регистрации событий (по крайней мере, на мой взгляд) ). Концепция взята из макроса dbg!() Rust.

Полный код находится здесь, в репозитории GitHub Я не ожидаю, что вы это сделаете, но если вы знаете ответ, приветствуется запрос на извлечение.

NPM пакет

Мой пакет позволяет это:

dbg(() => age); // logs '[/src/index.js:25] age = 25'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...