TypeScript 함수들이 어떻게 호출될 수 있는지를 설명하는 방법을 알아보자

1. **Function Type Expressions(**함수 타입 유형식)

// (a: string)의 의미는 fn 함수는 a에 string Type인 파라미터를 가진 함수의 뜻이다. 
// Type을 지정하지 않을 시에는 암묵적으로 any Type이 지정된다.
function greeter(fn: (a: string) => void) {
  fn("Hello, World");
}

// 물론 위 형식을 아래와 같이 'type alias'로 사용 가능하다.
type GreetFunction = (a: string) => void;
function greeter(fn: GreetFunction) {
  // ...
}
 
function printToConsole(s: string) {
  console.log(s);
}
 
greeter(printToConsole);

2. Call Signatures(호출 시그니처)

type DescribableFunction = {
  description: string;
  (someArg: number): boolean;
};
function doSomething(fn: DescribableFunction) {
  console.log(fn.description + " returned " + fn(6));
}

함수 유형식(Function type expression)은 =>를 사용하고 개체 유형식(Call Signatures)은 : 을 사용한다.

3. Construct Signatures(구성 시그니처)

생성자 함수 타입 지정 방식이다

type SomeConstructor = {
  new (s: string): SomeObject;
};
function fn(ctor: SomeConstructor) {
  return new ctor("hello");
}

상수 유형식을 활용하여 아래와 같이 사용할 수 있다.

interface CallOrConstruct {
  new (s: string): Date; // construct
  (n?: number): number; // call
}

// construct
let object: Date = new CallOrConstruct("optional string s");
// call
let myNumber: number = CallOrConstruct(/* n= */ 42);

하나의 함수 객체가 두 가지 목적을 수행하는 경우 TypeScript로 양쪽 모두 타입을 지정하여 결합시킬 수 있다.

4. 제네릭 함수

제네릭 문법이 두 값 사이에 상관관계를 표현하기 위해 사용된다.

function firstElement<Type>(arr: Type[]): Type | undefined {
  return arr[0];
}

// s는 "string" 타입
const s = firstElement(["a", "b", "c"]);
// n은 "number" 타입
const n = firstElement(ㅏ[1ㅈ, 2, 3]);
// u는 "undefined" 타입
const u = firstElement([]);

추론

Type을 특정하지 않았음에도 Type을 자동적으로 추론합니다.

function map<Input, Output>(arr: Input[], func: (arg: Input) => Output): Output[] {
  return arr.map(func);
}
 
const parsed = map(["1", "2", "3"], (n) => parseInt(n));
/*
	여기서의 매개변수 n은 type이 string으로 추론되며, 
	parsed의 type은 number[] type으로 추론한다.
*/