Hiện tại tôi có định nghĩa kiểu như:
interface Param {
title: string;
callback: any;
}
Tôi cần một cái gì đó như:
interface Param {
title: string;
callback: function;
}
nhưng cái thứ 2 không được chấp nhận.
Hiện tại tôi có định nghĩa kiểu như:
interface Param {
title: string;
callback: any;
}
Tôi cần một cái gì đó như:
interface Param {
title: string;
callback: function;
}
nhưng cái thứ 2 không được chấp nhận.
Câu trả lời:
Loại toàn cầu Function
phục vụ mục đích này.
Ngoài ra, nếu bạn có ý định gọi lại cuộc gọi này với 0 đối số và sẽ bỏ qua giá trị trả về của nó, loại () => void
khớp với tất cả các hàm không có đối số.
Function
như trong dòng đầu tiên của câu trả lời này không, và nói đoạn thứ hai (sử dụng loại () => void
hoặc bất cứ điều gì phù hợp với trường hợp sử dụng) được ưu tiên?
Bản đánh máy từ v1.4 có type
từ khóa khai báo bí danh loại (tương tự như typedef
trong C / C ++). Bạn có thể khai báo kiểu gọi lại của mình, do đó:
type CallbackFunction = () => void;
trong đó khai báo một hàm không có đối số và không trả về gì. Hàm lấy không hoặc nhiều đối số thuộc bất kỳ loại nào và trả về không có gì sẽ là:
type CallbackFunctionVariadic = (...args: any[]) => void;
Sau đó, bạn có thể nói, ví dụ,
let callback: CallbackFunctionVariadic = function(...args: any[]) {
// do some stuff
};
Nếu bạn muốn một hàm lấy số lượng đối số tùy ý và trả về bất cứ thứ gì (bao gồm khoảng trống):
type CallbackFunctionVariadicAnyReturn = (...args: any[]) => any;
Bạn có thể chỉ định một số đối số bắt buộc và sau đó là một tập hợp các đối số bổ sung (giả sử một chuỗi, một số và sau đó là một tập hợp các đối số phụ), do đó:
type CallbackFunctionSomeVariadic =
(arg1: string, arg2: number, ...args: any[]) => void;
Điều này có thể hữu ích cho những thứ như trình xử lý EventEuctor.
Các chức năng có thể được gõ mạnh như bạn muốn trong thời trang này, mặc dù bạn có thể bị mang đi và gặp phải các vấn đề liên hợp nếu bạn cố gắng khắc phục mọi thứ bằng một bí danh loại.
Function
và (...args: any[]) => any
những gì được ưa thích?
...args: any[]
không hữu ích lắm
type CallbackFunctionSomeVariadic = (arg1: string, arg2: number, ...args: any[]) => void;
những gì tôi đang tìm kiếm, ty.
Đây là một ví dụ về chức năng chấp nhận gọi lại
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
});
Nếu bạn không quan tâm đến giá trị trả về của các cuộc gọi lại (hầu hết mọi người không biết cách sử dụng chúng theo bất kỳ cách hiệu quả nào), bạn có thể sử dụng 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
});
Lưu ý, chữ ký tôi đã sử dụng cho callback
tham số ...
const sqk = (x: number, callback: ((_: number) => number)): number
Tôi muốn nói rằng đây là một thiếu sót TypeScript vì chúng tôi dự kiến sẽ cung cấp một tên cho các tham số gọi lại. Trong trường hợp này tôi đã sử dụng _
vì nó không thể sử dụng được bên trongsqk
hàm.
Tuy nhiên, nếu bạn làm điều này
// danger!! don't do this
const sqk = (x: number, callback: ((number) => number)): number
Đó là TypeScript hợp lệ , nhưng nó sẽ được hiểu là ...
// watch out! typescript will think it means ...
const sqk = (x: number, callback: ((number: any) => number)): number
Tức là, TypeScript sẽ nghĩ tên tham số là number
và kiểu ngụ ý là any
. Đây rõ ràng không phải là những gì chúng tôi dự định, nhưng than ôi, đó là cách TypeScript hoạt động.
Vì vậy, đừng quên cung cấp tên tham số khi nhập tham số chức năng của bạn ... thật ngu ngốc.
Bạn có thể định nghĩa một loại chức năng trong giao diện theo nhiều cách khác nhau,
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;
}
Sử dụng là rất thẳng về phía trước,
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;
}
Có bốn loại hàm trừu tượng, bạn có thể sử dụng chúng một cách riêng biệt khi bạn biết hàm của mình sẽ có (các) đối số hay không, sẽ trả về dữ liệu hay không.
export declare type fEmptyVoid = () => void;
export declare type fEmptyReturn = () => any;
export declare type fArgVoid = (...args: any[]) => void;
export declare type fArgReturn = (...args: any[]) => any;
như thế này:
public isValid: fEmptyReturn = (): boolean => true;
public setStatus: fArgVoid = (status: boolean): void => this.status = status;
Để chỉ sử dụng một loại như bất kỳ loại chức năng nào, chúng tôi có thể kết hợp tất cả các loại trừu tượng lại với nhau, như thế này:
export declare type fFunction = fEmptyVoid | fEmptyReturn | fArgVoid | fArgReturn;
sau đó sử dụng nó như sau:
public isValid: fFunction = (): boolean => true;
public setStatus: fFunction = (status: boolean): void => this.status = status;
Trong ví dụ trên mọi thứ đều đúng. Nhưng ví dụ sử dụng dưới đây không đúng theo quan điểm của hầu hết các biên tập viên mã.
// 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();
}
Gọi chính xác cho các biên tập viên là như thế này:
public callArgument(callback: fFunction) {
// pay attention in this part, for fix editor(s) error
(callback as fFunction)();
}
Bản mô tả: Làm thế nào để xác định loại cho một hàm gọi lại được sử dụng trong một tham số phương thức ?
Bạn có thể khai báo callback như 1) sở hữu chức năng hoặc 2) phương pháp :
interface ParamFnProp {
callback: (a: Animal) => void; // function property
}
interface ParamMethod {
callback(a: Animal): void; // method
}
Có một sự khác biệt quan trọng về gõ kể từ TS 2.6 :
Bạn nhận được các loại mạnh hơn ("âm thanh") trong --strict
hoặc --strictFunctionTypes
chế độ, khi một thuộc tính chức năng được khai báo. Hãy lấy một ví dụ:
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 ...
Về mặt kỹ thuật nói, phương pháp này bivariant và tính chức năng contravariant trong lập luận của họ dưới strictFunctionTypes
. Các phương thức vẫn được kiểm tra một cách dễ dàng hơn (ngay cả khi không có âm thanh) để thực tế hơn một chút khi kết hợp với các loại tích hợp nhưArray
.