Итак, я хочу создать функцию negate
, которая принимает некоторую функцию, которая возвращает логическое значение для некоторого списка аргументов и возвращает функция, которая принимает те же аргументы и выдает абсолютно противоположный логический результат.Функция, которая выполняет функцию предиката (возвращает логическое значение) и возвращает функцию предиката с теми же параметрами
Это возможно, если мы уйдем безопасность типа нереально:
function negate(predicate: Function): Function {
return function() {
return !predicate.apply(this, arguments);
}
}
Мы можем даже указать, что результирующая функция возвращает логическое значение, используя () => boolean
в качестве возвращаемого типа. Но эта сигнатура указывает, что возвращаемая функция не принимает аргументов - на самом деле она должна иметь точно такие же аргументы, как и в функции predicate
.
Что бы я хотел - это указать это. Если ограничить predicate
ровно один параметр, я могу:
function negate<A>(predicate: (a: A) => boolean): (a: A) => boolean {
return function (a: A) {
return !predicate.apply(this, arguments);
}
}
И я мог бы использовать перегрузку, чтобы указать это на ноль, один, два, и так далее параметров, вручную определяя каждую версию. В какой-то момент я смогу принять столько параметров, сколько должна разумно принимать любая функция. И расширение его с еще большим количеством параметров, если мое определение «разумное» расширяется, не ужасно много работы.
В качестве альтернативы, this answer предлагает другую тактику:
export function negate<Predicate extends Function>(p: Predicate): Predicate {
return <any> function() {
!p.apply(this, arguments);
}
}
Который является типобезопасным так долго, как предикат фактически делает возвращает логический но не имеет никакого способа ограничения параметров для вещей, которые возвращают логическое значение (и, что еще хуже, это беззвучно произнесет любой небулевой результат, который вы получите в логическом порядке, чтобы применить !
, и это не будет указано в сигнатуре возвращаемой функции).
Так что я действительно хотел бы быть как полностью типобезопасный и DRY.
Есть ли в машинописном машиностроении какие-либо функции, которые сделают это возможным?
@basarat Хотя подобное, я не думаю, что это * копия * вопрос, из-за требования здесь, что переданное в функцию возврата 'boolean'. Отредактировал заголовок, чтобы сосредоточиться на этом. – KRyan