В даний час у мене є визначення типу:
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.