선언 레퍼런스

선언 레퍼런스 (예제로 배우기)/도입/

이 페이지는 TypeScript 공식 문서에서 고품질 정의 파일(즉 .d.ts 파일)을 어떻게 쓰는지 알려주는 안내서예요. 설명 방식이 조금 특별한데, 어떤 API가 "이렇게 문서화되어 있고", 그 API가 "이렇게 사용되고", 그럼 "이에 맞는 선언(declaration)을 어떻게 써야 하는지"를 세트로 보여줘요. 마치 옆에서 하나씩 짚어주는 느낌이라고 생각하면 돼요.

예제들은 대략적으로 난이도가 낮은 순서부터 높은 순서로 정렬되어 있답니다. 차근차근 따라가면 자연스럽게 감이 잡힐 거예요.

출처: TypeScript 공식문서

본문

속성을 가진 객체 (Objects with Properties)

먼저 전역 변수 myLib 하나에 함수와 프로퍼티가 같이 들어 있는 경우예요. makeGreeting은 인사말을 만드는 함수이고, numberOfGreetings는 지금까지 만든 인사말의 개수를 나타내는 프로퍼티예요.

Code

let result = myLib.makeGreeting("hello, world");

console.log("The computed greeting is:" + result);

let count = myLib.numberOfGreetings;

Declaration

점(.)으로 접근하는 표기법(dotted notation)으로 쓰는 타입이나 값을 설명할 때는 declare namespace를 사용해요.

declare namespace myLib {
  function makeGreeting(s: string): string;
  let numberOfGreetings: number;
}

오버로드된 함수 (Overloaded Functions)

같은 이름의 getWidget 함수인데, 인자로 숫자를 받으면 Widget 하나를 반환하고, 문자열을 받으면 Widget 배열을 반환하는 경우예요. 이렇게 같은 이름에 시그니처가 여러 개인 걸 오버로드(overload) 라고 해요.

Code

let x: Widget = getWidget(43);

let arr: Widget[] = getWidget("all of them");

Declaration

오버로드는 declare function을 인자 시그니처만 바꿔서 여러 번 선언하면 돼요.

declare function getWidget(n: number): Widget;
declare function getWidget(s: string): Widget[];

재사용할 수 있는 타입 (인터페이스, Interfaces)

인사말을 지정할 때는 GreetingSettings라는 객체를 꼭 넘겨야 해요. 이 객체가 가진 프로퍼티는 세 가지예요.

  • greeting: 필수 문자열 (Mandatory string)
  • duration: 선택 항목, 밀리초 단위의 시간 (Optional)
  • color: 선택 항목, 문자열 (예: '#ff00ff')

Code

greet({
  greeting: "hello world",
  duration: 4000
});

Declaration

프로퍼티를 가진 타입을 정의할 때는 interface를 사용해요. 선택 항목은 ?를 붙이면 된답니다.

interface GreetingSettings {
  greeting: string;
  duration?: number;
  color?: string;
}

declare function greet(setting: GreetingSettings): void;

재사용할 수 있는 타입 (타입 별칭, Type Aliases)

인사말이 필요한 자리라면 string을 넘겨도 되고, string을 반환하는 함수를 넘겨도 되고, Greeter 인스턴스를 넘겨도 되는 경우예요. 이렇게 "여러 형태 중 하나"를 허용할 때 타입 별칭이 유용해요.

Code

function getGreeting() {
  return "howdy";
}

class MyGreeter extends Greeter {}

greet("hello");
greet(getGreeting);
greet(new MyGreeter());

Declaration

type으로 타입의 축약형(shorthand)을 만들어두면 돼요. | 로 나열된 유니온 타입이라서 세 가지 중 아무거나 받을 수 있어요.

type GreetingLike = string | (() => string) | MyGreeter;

declare function greet(g: GreetingLike): void;

타입 정리하기 (Organizing Types)

greeter 객체는 파일에 로그를 남기거나(.log), 알림창을 띄울(.alert) 수 있어요. .log(...)에는 LogOptions를, .alert(...)에는 alert용 옵션을 넘겨줄 수 있어요.

Code

const g = new Greeter("Hello");
g.log({ verbose: true });
g.alert({ modal: false, title: "Current Greeting" });

Declaration

연관된 타입들을 묶어서 정리할 때는 namespace를 사용해요.

declare namespace GreetingLib {
  interface LogOptions {
    verbose?: boolean;
  }
  interface AlertOptions {
    modal: boolean;
    title?: string;
    color?: string;
  }
}

하나의 선언 안에서 namespace를 중첩(nested) 으로 만드는 것도 가능해요.

declare namespace GreetingLib.Options {
  // Refer to via GreetingLib.Options.Log
  interface Log {
    verbose?: boolean;
  }
  interface Alert {
    modal: boolean;
    title?: string;
    color?: string;
  }
}

이렇게 하면 GreetingLib.Options.Log 같은 식으로 점 표기법을 통해 참조하게 돼요.

클래스 (Classes)

Greeter 객체를 인스턴스화해서 greeter를 새로 만들 수도 있고, 그걸 상속(extend)해서 나만의 greeter를 만들 수도 있어요.

Code

const myGreeter = new Greeter("hello, world");
myGreeter.greeting = "howdy";
myGreeter.showGreeting();

class SpecialGreeter extends Greeter {
  constructor() {
    super("Very special greetings");
  }
}

Declaration

클래스나 클래스처럼 생긴 객체를 설명할 때는 declare class를 사용해요. 클래스는 프로퍼티와 메서드를 가질 수 있고, 생성자(constructor)도 가질 수 있어요.

declare class Greeter {
  constructor(greeting: string);
  greeting: string;
  showGreeting(): void;
}

전역 변수 (Global Variables)

전역 변수 foo가 현재 위젯의 개수를 담고 있는 경우예요.

Code

console.log("Half the number of widgets is " + foo / 2);

Declaration

변수는 declare var로 선언해요. 읽기 전용이라면 declare const를, 블록 스코프 변수라면 declare let을 쓸 수도 있어요.

/** The number of widgets present */
declare var foo: number;

전역 함수 (Global Functions)

전역에서 greet 함수를 문자열과 함께 호출해서 사용자에게 인사말을 보여주는 경우예요.

Code

greet("hello, world");

Declaration

함수는 declare function으로 선언해요.

declare function greet(greeting: string): void;

더 알아보기