Typescript : 메소드 매개 변수에 사용되는 함수 콜백의 유형을 정의하는 방법 (범용이 아닌 모든 함수 유형)


313

현재 유형 정의는 다음과 같습니다.

interface Param {
    title: string;
    callback: any;
}

나는 다음과 같은 것이 필요하다 :

interface Param {
    title: string;
    callback: function;
}

그러나 두 번째 것은 받아 들여지지 않습니다.

답변:


285

전역 유형 Function이이 목적에 사용됩니다.

또한 0 개의 인수로이 콜백을 호출하려는 경우 반환 값을 무시하면 형식 () => void은 인수를 사용하지 않는 모든 함수와 일치합니다.


27

13
인수를 정의하고 값을 반환해야하므로 기본 유형이 아닙니다. 콜백과 같은 것 : (number : number) => void; 콜백보다 유형 검사에 훨씬 유용합니다. function; 될 것입니다.
kpup

@kpup 분명히, 이 답변의 첫 번째 줄에 표시된 것처럼 대문자 F를 사용 하지 말라고Function 말하고 두 번째 단락 ( () => void유스 케이스의 유형 또는 일치하는 것을 사용)을 말하는 것이 선호됩니까?
ruffin

2
FWIW는 기능 유형에 대한 문서를 사용할 수 있습니다 여기에
imjared

191

v1.4의 Typescript type에는 유형 별명을 선언하는 키워드가 있습니다 ( typedefC / C ++의 경우 와 유사 ). 콜백 유형을 다음과 같이 선언 할 수 있습니다.

type CallbackFunction = () => void;

인수를 사용하지 않고 아무것도 반환하지 않는 함수를 선언합니다. 모든 유형의 인수가 0 개 이상이고 아무것도 반환하지 않는 함수는 다음과 같습니다.

type CallbackFunctionVariadic = (...args: any[]) => void;

예를 들어

let callback: CallbackFunctionVariadic = function(...args: any[]) {
  // do some stuff
};

임의의 수의 인수를 사용하고 아무것도 포함하지 않는 함수를 원한다면 (void 포함) :

type CallbackFunctionVariadicAnyReturn = (...args: any[]) => any;

일부 필수 인수와 추가 인수 세트 (예 : 문자열, 숫자 및 추가 인수 세트)를 지정할 수 있습니다.

type CallbackFunctionSomeVariadic =
  (arg1: string, arg2: number, ...args: any[]) => void;

이것은 EventEmitter 핸들러와 같은 것들에 유용 할 수 있습니다.

유형 별명을 사용하여 모든 항목을 정리하려고 시도하면 조합 식 문제가 발생할 수 있지만 이러한 방식으로 원하는대로 함수를 강력하게 입력 할 수 있습니다.


1
사이 Function그리고 (...args: any[]) => any무엇을 선호합니까?
ahong

@ ahong : 개인적으로 나는 서명을 제공하기 때문에 후자를 선호합니다 ... 일반적으로. ...args: any[]별로 유용하지 않습니다.
Ed S.

type CallbackFunctionSomeVariadic = (arg1: string, arg2: number, ...args: any[]) => void;내가 찾던 것, ty.
aqteifan

61

Ryan의 답변에 따르면 찾고있는 인터페이스는 다음과 같이 정의됩니다.

interface Param {
    title: string;
    callback: () => void;
}

34

다음은 콜백을 허용하는 함수의 예입니다.

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

그것은의 유효 타이프 라이터, 그러나 그것은으로 해석됩니다 ...

// watch out! typescript will think it means ...
const sqk = (x: number, callback: ((number: any) => number)): number

즉, TypeScript는 매개 변수 이름number묵시적 유형 이라고 생각합니다 any. 이것은 분명히 우리가 의도 한 것이 아니라 슬프게도 TypeScript가 작동하는 방식입니다.

따라서 함수 매개 변수를 입력 할 때 매개 변수 이름을 제공하는 것을 잊지 마십시오. 어리석은 것처럼 보일 수 있습니다.


32

다양한 방식으로 인터페이스에서 함수 유형을 정의 할 수 있습니다.

  1. 일반적인 방법 :
export interface IParam {
  title: string;
  callback(arg1: number, arg2: number): number;
}
  1. 속성 구문을 사용하려면
export interface IParam {
  title: string;
  callback: (arg1: number, arg2: number) => number;
}
  1. 함수 유형을 먼저 선언하면
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;
}
  1. 함수 유형 리터럴을 선언 할 수도 있습니다. 즉, 함수는 다른 함수를 매개 변수로 사용할 수 있습니다. 매개 변수화 함수는 콜백이라고도합니다.
export interface IParam{
  title: string;
  callback(lateCallFn?:
             (arg1:number,arg2:number)=>number):number;

}

10

네 가지 추상 함수 유형이 있습니다. 함수가 인수를 받거나받지 않거나 데이터를 반환할지 여부를 알 때 별도로 사용할 수 있습니다.

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)();
}

2

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 됩니다.

요약

  • 함수 속성과 메서드 선언에는 형식 차이가 있습니다
  • 가능하면 더 강한 유형의 함수 속성을 선택하십시오.

운동장 샘플 코드

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.