В TypeScript я могу объявить параметр функции как тип Function. Есть ли «безопасный для типов» способ сделать это, что мне не хватает? Например, рассмотрим это:
class Foo {
save(callback: Function) : void {
//Do the save
var result : number = 42; //We get a number from the save operation
//Can I at compile-time ensure the callback accepts a single parameter of type number somehow?
callback(result);
}
}
var foo = new Foo();
var callback = (result: string) : void => {
alert(result);
}
foo.save(callback);
Функция обратного вызова save не является безопасной для типов, я даю ей функцию обратного вызова, где параметром функции является строка, но я передаю ей число и компилирую без ошибок. Можно ли сделать параметр результата в функции сохранения типа безопасной?
TL; версия DR: есть ли в TypeScript эквивалент делегата .NET?
источник
(n: number) => any
значит какая-то функция подписи?number
), но тип возвращаемого значения вообще не ограничен (может быть любым значением или дажеvoid
)n
в этом синтаксисе? Разве одних типов ввода и вывода будет недостаточно?Вот TypeScript-эквиваленты некоторых распространенных делегатов .NET:
источник
Action
иFunc
делегаты, и делегаты устраняют большую часть потребности в конкретных типах делегатов и, что интересно, дают C # a подобие структурной типизации. Недостатком этих делегатов является то, что их имена не имеют никакого значения, но другие преимущества, как правило, перевешивают это. В TypeScript нам просто не нужны эти типы. Таким образом, анти-шаблон будетfunction map<T, U>(xs: T[], f: Func<T, U>)
. Предпочитаюfunction map<T, U>(xs: T[], f: (x: T) => U)
Я понимаю, что этот пост старый, но есть более компактный подход, который немного отличается от того, о чем просили, но может быть очень полезной альтернативой. Вы можете существенно объявить функцию в линии при вызове метода (
Foo
«ыsave()
в данном случае). Это будет выглядеть примерно так:Этот
multipleCallback()
подход очень полезен для таких вещей, как сетевые вызовы, которые могут быть успешными или неудачными. Опять же, предполагая пример сетевого вызова, когда онmultipleCallbacks()
вызывается, поведение как для успеха, так и для отказа может быть определено в одном месте, что обеспечивает большую ясность для будущих читателей кода.В целом, по моему опыту, этот подход позволяет быть более кратким, менее беспорядочным и большей ясностью в целом.
Всем удачи!
источник
Это, безусловно, согласуется с парадигмой функционального программирования.
источник
inputType
а неreturnType
, не так ли? ГдеinputType
тип, вdata
который вы передаете параметрcallback
функции.В TS мы можем вводить функции следующими способами:
Типы функций / подписи
Используется для реальных реализаций функций / методов, имеет следующий синтаксис:
Пример:
Тип функции Литералы
Литералы типа функции - это еще один способ объявить тип функции. Они обычно применяются в сигнатуре функции высшего порядка. Функция более высокого порядка - это функция, которая принимает функции в качестве параметров или возвращает функцию. Он имеет следующий синтаксис:
Пример:
источник
Если вы сначала определите тип функции, то это будет выглядеть так
Без типа функции с использованием синтаксиса простого свойства это будет:
Если вы хотите использовать интерфейсную функцию, такую как обобщенные делегаты c #, это будет:
источник
Помимо того, что сказали другие, общая проблема заключается в объявлении типов той же функции, которая перегружена. Типичным случаем является метод EventEmitter on (), который будет принимать несколько типов слушателей. Подобное может произойти при работе с избыточными действиями - и там вы используете тип действия как литерал для обозначения перегрузки. В случае EventEmitters вы используете литеральный тип имени события:
источник