В даний час у мене є визначення типу:
interface Param {
title: string;
callback: any;
}
Мені потрібно щось на кшталт:
interface Param {
title: string;
callback: function;
}
але 2-го не приймається.
В даний час у мене є визначення типу:
interface Param {
title: string;
callback: any;
}
Мені потрібно щось на кшталт:
interface Param {
title: string;
callback: function;
}
але 2-го не приймається.
Відповіді:
Глобальному типу Function
служить цій цілі.
Крім того, якщо ви маєте намір викликати цей зворотний дзвінок з 0 аргументами і буде ігнорувати його повернене значення, тип () => void
відповідає всім функціям без аргументів.
Function
як показано в першому рядку цієї відповіді, і говорити, що другий абзац (використовуючи тип () => void
або що відповідає випадку використання) є кращим?
Typescript від v1.4 має type
ключове слово, яке оголошує псевдонім типу (аналогічний a typedef
в C / C ++). Ви можете оголосити тип зворотного дзвінка таким чином:
type CallbackFunction = () => void;
яка оголошує функцію, яка не бере аргументів і нічого не повертає. Функція, яка бере нуль або більше аргументів будь-якого типу і нічого не повертає, буде:
type CallbackFunctionVariadic = (...args: any[]) => void;
Тоді ви можете сказати, наприклад,
let callback: CallbackFunctionVariadic = function(...args: any[]) {
// do some stuff
};
Якщо ви хочете, щоб функція приймала довільну кількість аргументів і повертала що-небудь (включаючи недійсне):
type CallbackFunctionVariadicAnyReturn = (...args: any[]) => any;
Ви можете вказати деякі обов'язкові аргументи, а потім набір додаткових аргументів (скажімо, рядок, число, а потім набір додаткових аргументів) таким чином:
type CallbackFunctionSomeVariadic =
(arg1: string, arg2: number, ...args: any[]) => void;
Це може бути корисно для таких речей, як обробники EventEmitter.
Функції можна вводити настільки сильно, як вам подобається таким чином, хоча ви можете захопитися і зіткнутися з комбінаторними проблемами, якщо спробуєте забити все внизу псевдонімом типу.
Function
і (...args: any[]) => any
що перевагу?
...args: any[]
не дуже корисно.
type CallbackFunctionSomeVariadic = (arg1: string, arg2: number, ...args: any[]) => void;
що я шукав, ти.
Виходячи з відповіді Райана, я думаю, що інтерфейс, який ви шукаєте, визначається наступним чином:
interface Param {
title: string;
callback: () => void;
}
Ось приклад функції, яка приймає зворотний дзвінок
const sqk = (x: number, callback: ((_: number) => number)): number => {
// callback will receive a number and expected to return a number
return callback (x * x);
}
// here our callback will receive a number
sqk(5, function(x) {
console.log(x); // 25
return x; // we must return a number here
});
Якщо вам не байдуже значення повернення зворотних викликів (більшість людей не знає, як їх ефективно використовувати), ви можете використовувати void
const sqk = (x: number, callback: ((_: number) => void)): void => {
// callback will receive a number, we don't care what it returns
callback (x * x);
}
// here our callback will receive a number
sqk(5, function(x) {
console.log(x); // 25
// void
});
Зауважте, підпис, який я використовував для callback
параметра ...
const sqk = (x: number, callback: ((_: number) => number)): number
Я б сказав, що це недолік TypeScript, оскільки, як очікується, ми надамо ім'я параметрів зворотного виклику. У цьому випадку я використовував, _
тому що він не використовується в sqk
функції.
Однак якщо ви це зробите
// danger!! don't do this
const sqk = (x: number, callback: ((number) => number)): number
Це дійсний TypeScript, але він інтерпретується як ...
// watch out! typescript will think it means ...
const sqk = (x: number, callback: ((number: any) => number)): number
Тобто TypeScript подумає, що ім'я параметра є, number
а тип - мається на увазі any
. Це, очевидно, не те, що ми мали намір, але, на жаль, саме так працює TypeScript.
Тому не забувайте вводити імена параметрів під час введення параметрів функції ... дурно, як може здатися.
Ви можете визначити тип функції в інтерфейсі різними способами,
export interface IParam {
title: string;
callback(arg1: number, arg2: number): number;
}
export interface IParam {
title: string;
callback: (arg1: number, arg2: number) => number;
}
type MyFnType = (arg1: number, arg2: number) => number;
export interface IParam {
title: string;
callback: MyFnType;
}
Використання дуже прямо вперед,
function callingFn(paramInfo: IParam):number {
let needToCall = true;
let result = 0;
if(needToCall){
result = paramInfo.callback(1,2);
}
return result;
}
export interface IParam{
title: string;
callback(lateCallFn?:
(arg1:number,arg2:number)=>number):number;
}
Існує чотири абстрактні типи функцій, ви можете використовувати їх окремо, коли знаєте, що ваша функція прийме аргументи (аргументи) чи ні, поверне дані чи ні.
export declare type fEmptyVoid = () => void;
export declare type fEmptyReturn = () => any;
export declare type fArgVoid = (...args: any[]) => void;
export declare type fArgReturn = (...args: any[]) => any;
подобається це:
public isValid: fEmptyReturn = (): boolean => true;
public setStatus: fArgVoid = (status: boolean): void => this.status = status;
Для використання лише одного типу, як будь-якого типу функції, ми можемо комбінувати всі абстрактні типи разом, як це:
export declare type fFunction = fEmptyVoid | fEmptyReturn | fArgVoid | fArgReturn;
то використовуйте його так:
public isValid: fFunction = (): boolean => true;
public setStatus: fFunction = (status: boolean): void => this.status = status;
У наведеному вище прикладі все правильно. Але приклад використання нижче наведено неправильно з точки зору більшості редакторів коду.
// you can call this function with any type of function as argument
public callArgument(callback: fFunction) {
// but you will get editor error if call callback argument like this
callback();
}
Правильний дзвінок для редакторів виглядає так:
public callArgument(callback: fFunction) {
// pay attention in this part, for fix editor(s) error
(callback as fFunction)();
}
Typescript: Як визначити тип для зворотного виклику функції, який використовується в параметрі методу ?
Ви можете оголосити зворотний виклик як 1) властивість функції або 2) метод :
interface ParamFnProp {
callback: (a: Animal) => void; // function property
}
interface ParamMethod {
callback(a: Animal): void; // method
}
З TS 2.6 важлива різниця в наборі тексту :
Коли ви оголошуєте властивість функції, ви отримуєте сильніші ("звукові") типи в режимі --strict
або --strictFunctionTypes
режимі . Візьмемо приклад:
const animalCallback = (a: Animal): void => { } // Animal is the base type for Dog
const dogCallback = (d: Dog): void => { }
// function property variant
const param11: ParamFnProp = { callback: dogCallback } // error: not assignable
const param12: ParamFnProp = { callback: animalCallback } // works
// method variant
const param2: ParamMethod = { callback: dogCallback } // now it works again ...
З технічної точки зору , методи є двоваріантними та функціональними властивостями, суперечливими у своїх аргументах під strictFunctionTypes
. Методи все-таки перевіряються більш дозвільно (навіть якщо вони не звучать), щоб бути трохи практичнішими в поєднанні з вбудованими типами типу Array
.