diff --git a/docs/documentation/ko/Nightly Builds.md b/docs/documentation/ko/Nightly Builds.md new file mode 100644 index 00000000..36e1ad34 --- /dev/null +++ b/docs/documentation/ko/Nightly Builds.md @@ -0,0 +1,80 @@ +--- +title: Nightly Builds +layout: docs +permalink: /ko/docs/handbook/nightly-builds.html +oneline: How to use a nightly build of TypeScript +translatable: true +--- + +[TypeScript의 `master`](https://github.com/Microsoft/TypeScript/tree/master) 브랜치의 nightly 빌드는 태평양 표준시(PST) 자정까지 NPM에 배포됩니다. +도구를 사용하여 가져오는 방법과 사용하는 방법은 다음과 같습니다. + +## npm 사용하기 (Using npm) + +```shell +npm install -g typescript@next +``` + +## nightly 빌드를 사용하도록 IDE 업데이트 (Updating your IDE to use the nightly builds) + +nightly drop을 사용하도록 IDE를 업데이트할 수 있습니다. +먼저 npm을 통해 패키지를 설치해야 합니다. +npm 패키지를 전역으로 설치하거나 로컬에 있는 `node_modules` 폴더에 설치할 수 있습니다. + +이 섹션의 나머지 부분에서는 `typescript@next`가 이미 설치되어 있다고 가정합니다. + +### 비주얼 스튜디오 코드 (Visual Studio Code) + +`.vscode/settings.json` 파일을 다음과 같이 업데이트하세요: + +```json +"typescript.tsdk": "/node_modules/typescript/lib" +``` + +자세한 내용은 [VSCode 문서](https://code.visualstudio.com/Docs/languages/typescript#_using-newer-typescript-versions)를 참조하세요. + +### 서브라임 텍스트 (Sublime Text) + +`Settings - User` 파일을 다음과 같이 업데이트하세요: + +```json +"typescript_tsdk": "/node_modules/typescript/lib" +``` + +자세한 내용은 [서브라임 텍스트를 위한 TypeScript 플러그인 설치 문서](https://github.com/Microsoft/TypeScript-Sublime-Plugin#installation)를 참조하세요. + +### 비주얼 스튜디오 2013 및 2015 (Visual Studio 2013 and 2015) + +> 주의사항: 대부분의 변경 사항에는 새로운 버전의 VS TypeScript 플러그인을 설치할 필요는 없습니다. + +현재 nightly 빌드에는 전체 플러그인 설정이 포함되어 있지 않지만 nightly 기반으로 설치 프로그램을 배포하기 위해 노력하고 있습니다. + +1. [VSDevMode.ps1](https://github.com/Microsoft/TypeScript/blob/master/scripts/VSDevMode.ps1) 스크립트를 다운로드하세요. + + > 또한 [커스텀 언어 서비스 파일 사용](https://github.com/Microsoft/TypeScript/wiki/Dev-Mode-in-Visual-Studio#using-a-custom-language-service-file)에 대한 위키 페이지를 참조하세요. + +2. PowerShell 커맨드 라인 창에서 다음을 실행합니다: + +VS 2015: + +```posh +VSDevMode.ps1 14 -tsScript /node_modules/typescript/lib +``` + +VS 2013: + +```posh +VSDevMode.ps1 12 -tsScript /node_modules/typescript/lib +``` + +### IntelliJ IDEA (Mac) + +`Preferences` > `Languages & Frameworks` > `TypeScript`를 선택합니다: + + > TypeScript 버전: npm으로 설치한 경우: `/usr/local/lib/node_modules/typescript/lib` + +### IntelliJ IDEA (Windows) + +`File` > `Settings` > `Languages & Frameworks` > `TypeScript`를 선택합니다: + + > TypeScript 버전: npm으로 설치한 경우: `C:\Users\USERNAME\AppData\Roaming\npm\node_modules\typescript\lib` diff --git a/docs/documentation/ko/declaration-files/By Example.md b/docs/documentation/ko/declaration-files/By Example.md new file mode 100644 index 00000000..e73f5066 --- /dev/null +++ b/docs/documentation/ko/declaration-files/By Example.md @@ -0,0 +1,263 @@ +--- +title: Declaration Reference +layout: docs +permalink: /ko/docs/handbook/declaration-files/by-example.html +oneline: "How to create a d.ts file for a module" +--- + +# 소개 (Introduction) + +이 가이드는 양질의 선언 파일을 작성하는 방법을 설명하기 위해 작성되었습니다. +이 가이드는 일부 API 문서를 해당 API 사용 예시와 함께 보여주고, + 상응하는 선언을 작성하는 방법을 설명합니다. + +예제는 대체로 후반부로 갈수록 복잡해집니다. + +* [프로퍼티를 갖는 객체 (Objects with Properties)](#프로퍼티를-갖는-객체-objects-with-properties) +* [오버로드된 함수 (Overloaded Function)](#오버로드된-함수-overloaded-functions) +* [재사용 가능한 타입 (인터페이스) (Reusable Types (Interfaces))](#재사용-가능한-타입-인터페이스-reusable-types-interfaces) +* [재사용 가능한 타입 (타입 별칭) (Reusable Types (Type Aliases))](#재사용-가능한-타입-타입-별칭-reusable-types-type-aliases) +* [타입 구조화하기 (Organizing Types)](#타입-구조화하기-organizing-types) +* [클래스 (Classes)](#클래스-classes) +* [전역 변수 (Global Variables)](#전역-변수-global-variables) +* [전역 함수 (Global Functions)](#전역-함수-global-functions) + +# 예제 (The Examples) + +## 프로퍼티를 갖는 객체 (Objects with Properties) + +_문서_ + +> 전역 변수 `myLib`에는 인사말을 만드는 함수 `makeGreeting`와, +> 지금까지 생성한 인사말의 수를 가리키는 `numberOfGreetings` 프로퍼티가 있습니다. + +_코드_ + +```ts +let result = myLib.makeGreeting("hello, world"); +console.log("The computed greeting is:" + result); + +let count = myLib.numberOfGreetings; +``` + +_선언_ + +점 표기법으로 접근하는 타입이나 값을 설명하기 위해 `declare namespace`를 사용하세요. + +```ts +declare namespace myLib { + function makeGreeting(s: string): string; + let numberOfGreetings: number; +} +``` + +## 오버로드된 함수 (Overloaded Functions) + +_문서_ + +`getWidget` 함수는 숫자를 인자로 받아 Widget을 반환하거나, 문자열을 인자로 받아 Widget 배열을 반환합니다. + +_코드_ + +```ts +let x: Widget = getWidget(43); + +let arr: Widget[] = getWidget("all of them"); +``` + +_선언_ + +```ts +declare function getWidget(n: number): Widget; +declare function getWidget(s: string): Widget[]; +``` + +## 재사용 가능한 타입 (인터페이스) (Reusable Types (Interfaces)) + +_문서_ + +> greeting을 명시할 때, 반드시 `GreetingSettings` 객체를 전달해야 합니다. +> 이 객체는 다음의 프로퍼티를 갖고 있습니다: +> +> 1 - greeting: 필수 문자열 +> +> 2 - duration: 선택적 시간 (밀리초) +> +> 3 - color: 선택적 문자열, 예. '#ff00ff' + +_코드_ + +```ts +greet({ + greeting: "hello world", + duration: 4000 +}); +``` + +_선언_ + +프로퍼티를 갖는 타입을 정의하기 위해 `interface`를 사용하세요. + +```ts +interface GreetingSettings { + greeting: string; + duration?: number; + color?: string; +} + +declare function greet(setting: GreetingSettings): void; +``` + +## 재사용 가능한 타입 (타입 별칭) (Reusable Types (Type Aliases)) + +_문서_ + +> 인사말이 예상되는 어느 곳에나, `string`, `string`을 반환하는 함수, 또는 `Greeter` 인스턴스를 전달할 수 있습니다. + +_코드_ + +```ts +function getGreeting() { + return "howdy"; +} +class MyGreeter extends Greeter { } + +greet("hello"); +greet(getGreeting); +greet(new MyGreeter()); +``` + +_선언_ + +타입에 대한 약칭으로 타입 별칭을 사용할 수 있습니다: + +```ts +type GreetingLike = string | (() => string) | Greeter; + +declare function greet(g: GreetingLike): void; +``` + +## 타입 구조화하기 (Organizing Types) + +_문서_ + +> `greeter` 객체는 파일에 로그를 작성하거나 경고 창을 띄울 수 있습니다. +> 로그 옵션을 `.log(...)` 내부에, 경고 창 옵션을 `.alert(...)` 내부에 전달할 수 있습니다. + +_코드_ + +```ts +const g = new Greeter("Hello"); +g.log({ verbose: true }); +g.alert({ modal: false, title: "Current Greeting" }); +``` + +_선언_ + +타입을 구조화하기 위해 네임스페이스를 사용하세요. + +```ts +declare namespace GreetingLib { + interface LogOptions { + verbose?: boolean; + } + interface AlertOptions { + modal: boolean; + title?: string; + color?: string; + } +} +``` + +중첩된 네임스페이스를 하나의 선언으로 만들 수 있습니다: + +```ts +declare namespace GreetingLib.Options { + // Refer to via GreetingLib.Options.Log + interface Log { + verbose?: boolean; + } + interface Alert { + modal: boolean; + title?: string; + color?: string; + } +} +``` + +## 클래스 (Classes) + +_문서_ + +> `Greeter` 객체를 인스턴스화해서 greeter를 생성하거나, 이 객체를 상속해서 커스텀 greeter를 생성할 수 있습니다. + +_코드_ + +```ts +const myGreeter = new Greeter("hello, world"); +myGreeter.greeting = "howdy"; +myGreeter.showGreeting(); + +class SpecialGreeter extends Greeter { + constructor() { + super("Very special greetings"); + } +} +``` + +_선언_ + +클래스 혹은 클래스-같은 객체를 설명하기 위해 `declare class`를 사용하세요. +클래스는 생성자 뿐만 아니라 프로퍼티와 메서드를 가질 수 있습니다. + +```ts +declare class Greeter { + constructor(greeting: string); + + greeting: string; + showGreeting(): void; +} +``` + +## 전역 변수 (Global Variables) + +_문서_ + +> 전역 변수 `foo`는 존재하는 위젯의 수를 포함합니다. + +_코드_ + +```ts +console.log("Half the number of widgets is " + (foo / 2)); +``` + +_선언_ + +변수를 선언하기 위해 `declare var`를 사용하세요. +만약 변수가 읽기-전용이라면, `declare const`를 사용하세요. +변수가 블록-스코프인 경우 `declare let` 또한 사용할 수 있습니다. + +```ts +/** 존재하는 위젯의 수 */ +declare var foo: number; +``` + +## 전역 함수 (Global Functions) + +_문서_ + +> 사용자에게 인사말을 보여주기 위해 `greet` 함수를 호출할 수 있습니다. + +_코드_ + +```ts +greet("hello, world"); +``` + +_선언_ + +함수를 선언하기 위해 `declare function`을 사용하세요. + +```ts +declare function greet(greeting: string): void; +``` diff --git a/docs/documentation/ko/declaration-files/Consumption.md b/docs/documentation/ko/declaration-files/Consumption.md new file mode 100644 index 00000000..737e1d10 --- /dev/null +++ b/docs/documentation/ko/declaration-files/Consumption.md @@ -0,0 +1,47 @@ +--- +title: Consumption +layout: docs +permalink: /ko/docs/handbook/declaration-files/consumption.html +oneline: "How to download d.ts files for your project" +--- + +TypeScript 2.0에서는 선언 파일을 얻고, 사용하고, 찾는 것이 훨씬 쉬워졌습니다. +이 페이지에서 세 가지를 어떻게 하는지 정확하게 설명합니다. + +## 다운로드 (Downloading) + +TypeScript 2.0 이상에서 타입 선언을 가져오는데 npm 이외의 도구는 필요하지 않습니다. + +예를 들어, lodash와 같은 라이브러리에 대한 선언을 얻는 것은 다음 명령어로 충분합니다. + +```cmd +npm install --save @types/lodash +``` + +[Publishing](/docs/handbook/declaration-files/publishing.html)에서 설명한 대로 npm 패키지에 이미 선언 파일이 포함되어 있다면, `@types` 패키지를 설치할 필요는 없다는 걸 유의하세요. + +## 사용하기 (Consuming) + +TypeScript 코드에 별 어려움 없이 lodash를 사용할 수 있습니다. +이는 모듈 및 전역 코드에 모두 적용됩니다. + +예를 들어, 타입 선언에 대해 `npm install`을 한 번만 수행하면, import 하고 사용할 수 있고 + +```ts +import * as _ from "lodash"; +_.padStart("Hello TypeScript!", 20, " "); +``` + +또는 모듈을 사용하지 않는다면, 전역 변수 `_` 를 사용할 수 있습니다. + +```ts +_.padStart("Hello TypeScript!", 20, " "); +``` + +## 찾기 (Searching) + +대부분의 경우, 타입 선언 패키지 이름은 항상 `npm` 상의 패키지 이름과 같아야 하지만, `@types/` 가 앞에 붙어야 합니다. + 하지만 필요시 [https://aka.ms/types](https://aka.ms/types) 를 방문해 선호하는 라이브러리의 패키지를 찾으세요. + +> 참고: 만약 찾고자 하는 선언 파일이 없는 경우, 언제든지 기여하고, 다음 개발자가 이를 찾는 데 도움을 줄 수 있습니다. +> 자세한 내용은 DefinitelyTyped의 [기여 지침 페이지](http://definitelytyped.org/guides/contributing.html)를 참고하세요. \ No newline at end of file diff --git a/docs/documentation/ko/declaration-files/Deep Dive.md b/docs/documentation/ko/declaration-files/Deep Dive.md new file mode 100644 index 00000000..95f8db2f --- /dev/null +++ b/docs/documentation/ko/declaration-files/Deep Dive.md @@ -0,0 +1,238 @@ +--- +title: Deep Dive +layout: docs +permalink: /ko/docs/handbook/declaration-files/deep-dive.html +oneline: "How do d.ts files work, a deep dive" +--- + +## 정의 파일 이론: 심층 분석 (Definition File Theory: A Deep Dive) + +원하는 API 형태를 제공하는 모듈을 만드는 것은 까다로울 수 있습니다. +예를 들어, `new`의 사용에 따라 호출할 때 다른 타입을 생성하는 모듈을 원할 수 있고, + 계층에 노출 된 다양한 명명된 타입을 가지고 있으며, + 모듈 객체에 대한 여러 프로퍼티도 가질 수 있습니다. + +이 가이드에서는, 익숙한 API를 노출하는 복잡한 정의 파일에 대해 작성하는 도구를 제공합니다. +또한 옵션이 다양하기 때문에 여기서는 모듈 (또는 UMD) 라이브러리에 중점을 둡니다. + +## 주요 컨셉 (Key Concepts) + +TypeScript 작동 방식에 대해 여러 주요 개념을 이해하여 + 정의의 형태를 만드는 방법을 완전히 이해할 수 있습니다. + +### 타입 (Types) + +이 가이드를 읽고 있다면, 아마도 TypeScript의 타입에 대해 이미 알고 있을 것입니다. +보다 명확하게하기 위해, 다음과 같이 *타입*이 도입됩니다: + +* 타입 별칭 선언 (`type sn = number | string;`) +* 인터페이스 선언 (`interface I { x: number[]; }`) +* 클래스 선언 (`class C { }`) +* 열거형 선언 (`enum E { A, B, C }`) +* 타입을 가리키는 `import` 선언 + +이러한 각 선언 형태는 새로운 타입 이름을 만듭니다. + +### 값 (Values) + +타입과 마찬가지로 값이 무엇인지 이미 알고 있을 것입니다. +값은 표현식에서 참조할 수 있는 런타임 이름입니다. +예를 들어 `let x = 5;`에서는 `x`라고 불리는 값을 생성합니다. + +다시 명확하게 말하자면, 다음과 같이 값을 만듭니다: + +* `let`, `const`, 그리고 `var` 선언 +* 값을 포함하는 `네임스페이스` 또는 `모듈` 선언 +* `열거형` 선언 +* `클래스` 선언 +* 값을 참조하는 `import` 선언 +* `함수` 선언 + +### 네임스페이스 (Namespaces) + +타입은 *네임스페이스* 안에 존재할 수 있습니다. +예를 들어, `let x: A.B.C` 이란 선언이 있다면, + 타입 `C`는 `A.B` 네임스페이스에서 온 것 입니다. + +이 구별은 미묘하지만 중요합니다 -- 여기서 `A.B`는 타입이거나 값일 필요는 없습니다. + +## 간단한 조합: 하나의 이름, 여러 의미 (Simple Combinations: One name, multiple meanings) + +`A`라는 이름이 있으면, `A`에 대해 타입, 값 또는 네임스페이스라는 세 가지 다른 의미를 찾을 수 있습니다. +이름을 해석하는 방법은 사용하는 컨텍스트에 따라 다릅니다. +예를 들어 `let m: A.A = A;` 선언에서, + `A`는 먼저 네임스페이스로 사용 된 다음, 타입의 이름으로, 그 다음 값으로 사용됩니다. +즉 완전히 다른 선언을 의미할 수 있습니다! + +약간은 혼란스러워 보이지만, 과하게 사용하지 않는 한 실제로 매우 편리합니다. +결합 동작의 유용한 측면을 살펴 보겠습니다. + +### 내부 조합 (Built-in Combinations) + +영리한 사람이라면, *타입*과 *값* 목록에서 `클래스`가 둘 다 나온 것을 눈치챘을 것입니다. +`class C { }` 선언은 두 가지를 만듭니다: + 클래스 인스턴스의 형태를 나타내는 *타입* `C`와 + 클래스 생성자를 나타내는 *값* `C` 입니다. +열거형 선언도 비슷하게 동작합니다. + +### 사용자 조합 (User Combinations) + +모듈 파일 `foo.d.ts`을 작성했습니다: + +```ts +export var SomeVar: { a: SomeType }; +export interface SomeType { + count: number; +} +``` + +그 다음 사용했습니다: + +```ts +import * as foo from './foo'; +let x: foo.SomeType = foo.SomeVar.a; +console.log(x.count); +``` + +잘 작동하지만, `SomeType`과 `SomeVar`는 이름이 같도록 + 밀접하게 관련되어 있다고 상상할 수 있습니다. +결합을 사용하여 같은 이름 `Bar`로 두 가지 다른 객체 (값과 타입)를 표시 할 수 있습니다: + +```ts +export var Bar: { a: Bar }; +export interface Bar { + count: number; +} +``` + +이 경우 사용하는 코드를 구조 분해할 수 있는 아주 좋은 기회입니다: + +```ts +import { Bar } from './foo'; +let x: Bar = Bar.a; +console.log(x.count); +``` + +여기서도 `Bar`를 타입과 값으로 사용했습니다. +`Bar` 값을 `Bar` 타입으로 선언할 필요가 없다는 점을 유의하세요 -- 저 둘은 독립적입니다. + +## 고급 결합 (Advanced Combinations) + +선언은 여러 개의 선언에 걸쳐 결합될 수 있습니다. +예를 들어, `class C { }`와 `interface C { }` 같이 결합할 수 있으며 둘 다 `C` 타입에 프로퍼티를 추가합니다. + +충돌을 일으키지 않는다면 충분히 합법적입니다. +일반적인 경험 법칙은 값의 이름이 `네임스페이스`로 선언되지 않는 한 항상 같은 이름의 다른 값과 충돌하고, + 타입 별칭 선언(`type s = string`)으로 선언 된 경우 타입이 충돌하며, + 네임스페이스와는 절대로 충돌하지 않는 것입니다. + +어떻게 사용되는지 살펴보겠습니다. + +### `인터페이스`를 사용하여 추가하기 (Adding using an `interface`) + +`인터페이스`에 다른 `인터페이스` 선언을 사용하여 멤버를 추가할 수 있습니다: + +```ts +interface Foo { + x: number; +} +// ... 다른 위치 ... +interface Foo { + y: number; +} +let a: Foo = ...; +console.log(a.x + a.y); // 성공 +``` + +클래스와도 같이 동작합니다: + +```ts +class Foo { + x: number; +} +// ... 다른 위치 ... +interface Foo { + y: number; +} +let a: Foo = ...; +console.log(a.x + a.y); // 성공 +``` + +단, 타입 별칭 (`type s = string;`)에는 인터페이스를 사용해서 추가할 수 없습니다. + +### `네임스페이스`를 사용하여 추가하기 (Adding using a `namespace`) + +`네임스페이스` 선언은 충돌을 일으키지 않는 방식으로 새로운 타입, 값 그리고 네임스페이스를 추가할 수 있습니다. + +예를 들어, 클래스에 정적 멤버를 추가할 수 있습니다: + +```ts +class C { +} +// ... 다른 위치 ... +namespace C { + export let x: number; +} +let y = C.x; // 성공 +``` + +위 예제에서 `C`의 *정적* 측면(생성자 함수)에 값을 추가했습니다. +*값*을 추가 했고 모든 값에 대한 컨테이너가 다르기 때문입니다. + (타입은 네임스페이스에 포함되고 네임스페이스는 다른 네임스페이스에 포함됩니다). + +네임스페이스 타입을 클래스에 추가할 수 있습니다: + +```ts +class C { +} +// ... 다른 위치 ... +namespace C { + export interface D { } +} +let y: C.D; // 성공 +``` + +이 예제에서 `namespace` 선언을 작성할 때까지 네임스페이스 `C`는 없었습니다. +네임스페이스 `C`는 클래스에 의해 생성된 `C`의 값 또는 타입과 충돌하지 않습니다. + +마지막으로 `namespace` 선언을 사용하여 다양한 병합을 할 수 있습니다. +특히 현실적인 예는 아니지만, 흥미로운 동작을 확인할 수 있습니다: + +```ts +namespace X { + export interface Y { } + export class Z { } +} + +// ... 다른 위치 ... +namespace X { + export var Y: number; + export namespace Z { + export class C { } + } +} +type X = string; +``` + +위 예제에서 첫 번째 블록은 다음 이름의 의미를 만듭니다: + +* 값 `X` (`네임스페이스` 선언은 값 `Z`를 포함하기 때문입니다) +* 네임스페이스 `X` (`네임스페이스` 선언은 타입 `Y`를 포함하기 때문입니다) +* `X` 네임스페이스 안의 타입 `Y` +* `X` 네임스페이스 안의 타입 `Z` (클래스의 인스턴스 형태) +* `X` 값의 프로퍼티인 값 `Z` (클래스의 생성자 함수) + +두 번째 블록은 다음 이름의 의미를 만듭니다: + +* `X` 값의 프로퍼티인 값 `Y` (`number` 타입) +* 네임스페이스 `Z` +* `X` 값의 프로퍼티인 값 `Z` +* `X.Z` 네임스페이스 안의 타입 `C` +* `X.Z` 값의 프로퍼티인 값 `C` +* 타입 `X` + +## `export =` or `import` 사용하기 (Using with `export =` or `import`) + +중요한 규칙은 `export`와 `import` 선언이 대상의 *모든 의미* 를 내보내거나 가져온다는 것 입니다. + + diff --git a/docs/documentation/ko/declaration-files/Do's and Don'ts.md b/docs/documentation/ko/declaration-files/Do's and Don'ts.md new file mode 100644 index 00000000..7e4e32e9 --- /dev/null +++ b/docs/documentation/ko/declaration-files/Do's and Don'ts.md @@ -0,0 +1,228 @@ +--- +title: Do's and Don'ts +layout: docs +permalink: /ko/docs/handbook/declaration-files/do-s-and-don-ts.html +oneline: "Recommendations for writing d.ts files" +--- + +# 일반 타입 (General Types) + +## `Number`, `String`, `Boolean`, `Symbol` and `Object` + +`Number`, `String`, `Boolean`, `Symbol`, `Object` 타입을 사용*하지 마세요*. +이 타입들은 JavaScript 코드에서 거의 사용되지 않는 비-원시형 박싱된 객체를 가르킵니다. + +```ts +/* 잘못됨 */ +function reverse(s: String): String; +``` + +`number`, `string`, `boolean`, `symbol` 타입을 사용 *하세요*. + +```ts +/* 좋음 */ +function reverse(s: string): string; +``` + +`Object` 대신에, [TypeScript 2.2 에 추가된](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#object-type) 비-원시형 `object`타입을 사용*하세요*. + +## 제네릭 (Generics) + +타입 매개변수를 사용하지 않는 제네릭 타입을 사용*하지 마세요*. 더 자세한 내용은 [TypeScript FAQ 페이지](https://github.com/Microsoft/TypeScript/wiki/FAQ#why-doesnt-type-inference-work-on-this-interface-interface-foot---)에서 확인하세요. + + + +# 콜백 타입 (Callback Types) + +## 콜백의 반환 타입 (Return Types of Callbacks) + + + +사용하지 않는 콜백의 반환 값 타입에 `any`를 사용*하지 마세요*: + +```ts +/* 잘못됨 */ +function fn(x: () => any) { + x(); +} +``` + +사용하지 않는 콜백의 반환 값 타입은 `void`를 사용*하세요*: + +```ts +/* 좋음 */ +function fn(x: () => void) { + x(); +} +``` + +*이유*: `void`를 사용하면 실수로 `x`의 반환 값을 사용하는 것을 방지 할 수 있기 때문에 더 안전합니다.: + +```ts +function fn(x: () => void) { + var k = x(); // oops! meant to do something else + k.doSomething(); // error, but would be OK if the return type had been 'any' +} +``` + +## 콜백에서 선택적 매개변수 (Optional Parameters in Callbacks) + +정말 의도한 것이 아니라면 콜백에 선택적 매개변수를 사용*하지 마세요*: + +```ts +/* 잘못됨 */ +interface Fetcher { + getObject(done: (data: any, elapsedTime?: number) => void): void; +} +``` + +이는 아주 구체적인 의미를 가지고 있습니다: `done` 콜백은 1개 혹은 2개의 인자로 호출될 수 있습니다. +작성자는 아마 `elapsedTime` 매개변수가 콜백에 상관없다는 것을 말하려는 의도였을 것입니다, + 하지만 이를 위해 매개변수를 선택적으로 만들 필요는 없습니다 -- + 콜백에 더 적은 인수를 제공하는 것은 항상 허용됩니다. + +콜백 매개변수를 비-선택적으로 작성*하세요*: + +```ts +/* 좋음 */ +interface Fetcher { + getObject(done: (data: any, elapsedTime: number) => void): void; +} +``` + +## 오버로드와 콜백 (Overloads and Callbacks) + +콜백의 인수만 다른 오버로드를 분리해서 작성 *하지 마세요*: + +```ts +/* 잘못됨 */ +declare function beforeAll(action: () => void, timeout?: number): void; +declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void; +``` + +최대 인수를 사용해 하나의 오버로드를 작성 *하세요*: + +```ts +/* 좋음 */ +declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void; +``` + +*이유*: 콜백이 매개변수를 무시하는 것은 항상 허용되므로, 짧은 오버로드는 필요하지 않습니다. +더 짧은 콜백을 먼저 작성하면 넘어오는 함수가 첫 번째 오버로드와 일치하기 때문에 잘못된-타입의 함수를 허용합니다. + +# 함수 오버로드 (Function Overloads) + +## 순서 (Ordering) + +더 일반적인 오버로드를 더 구체적인 오버로드 이전에 두지 *마세요*: + +```ts +/* 잘못됨 */ +declare function fn(x: any): any; +declare function fn(x: HTMLElement): number; +declare function fn(x: HTMLDivElement): string; + +var myElem: HTMLDivElement; +var x = fn(myElem); // x: any, wat? +``` + +구체적인 오버로드 뒤에 일반적인 오버로드가 위치하게 정렬 *하세요*: + +```ts +/* 좋음 */ +declare function fn(x: HTMLDivElement): string; +declare function fn(x: HTMLElement): number; +declare function fn(x: any): any; + +var myElem: HTMLDivElement; +var x = fn(myElem); // x: string, :) +``` + +*이유*: TypeScript는 함수 호출을 처리할 때 *첫 번째로 일치하는 오버로드*를 선택합니다. +이전의 오버로드가 뒤에 것보다 "더 구체적"이면, 뒤에 것은 사실상 가려져 호출되지 않습니다. + +## 선택적 매개변수 사용 (Use Optional Parameters) + +뒤따라오는 매개변수만 다른 오버로드를 작성*하지 마세요*: + +```ts +/* 잘못됨 */ +interface Example { + diff(one: string): number; + diff(one: string, two: string): number; + diff(one: string, two: string, three: boolean): number; +} +``` + +가능한 선택적 매개변수를 사용 *하세요*: + +```ts +/* 좋음 */ +interface Example { + diff(one: string, two?: string, three?: boolean): number; +} +``` + +이 문제는 모든 오버로드가 같은 반환 타입을 가질 때만 발생한다는 점에 유의하세요. + +*이유*: 두 가지 중요한 이유가 있습니다. + +TypeScript는 소스의 인수로 대상의 시그니처를 호출할 수 있는지 확인하여 시그니처 호환성을 결정합니다. + *그리고 관계없는 인수가 허용됩니다* +예를 들어, 이 코드는 선택적 매개변수를 사용하여 올바르게 작성된 경우에만 버그를 노출합니다: + +```ts +function fn(x: (a: string, b: number, c: number) => void) { } +var x: Example; +// 오버로드로 작성한 경우, OK -- 첫번째 오버로드가 사용됨 +// 선택적으로 작성한 경우, 올바르게 오류. +fn(x.diff); +``` + +두 번째 이유는 사용자가 TypeScript의 "strict null checking" 기능을 사용할 때입니다. +JavaScript에서 지정되지 않은 매개변수는 `undefined`로 나타나기 때문에, 일반적으로 선택적 매개변수가 있는 함수에 명시적으로 `undefined`를 전달하는 것이 좋습니다. +예를 들어, 이 코드는, strict null에서 문제없습니다. + +```ts +var x: Example; +// 오버로드로 작성한 경우, `undefined`를 `string` 에 전달했기 때문에 잘못된 에러 +// 선택적으로 작성한 경우, 올바름 +x.diff("something", true ? undefined : "hour"); +``` + +## 유니언 타입 사용 (Use Union Types) + +한 인수 위치에서 타입만 다른 오버로드를 사용*하지 마세요*: + +```ts +/* 잘못됨 */ +interface Moment { + utcOffset(): number; + utcOffset(b: number): Moment; + utcOffset(b: string): Moment; +} +``` + +가능한 유니언 타입을 사용 *하세요*: + +```ts +/* 좋음 */ +interface Moment { + utcOffset(): number; + utcOffset(b: number|string): Moment; +} +``` + +시그니처의 반환 타입이 다르기 때문에 `b`를 선택적으로 만들지 않은 점에 유의하세요. + +*이유*: 이는 함수에 값을 "전달하는" 사람들에게 중요합니다.: + +```ts +function fn(x: string): void; +function fn(x: number): void; +function fn(x: number|string) { + // 분리된 오버로드로 작성된 경우, 잘못된 에러 + // 유니언 타입으로 작성된 경우, 올바름 + return moment().utcOffset(x); +} +``` diff --git a/docs/documentation/ko/declaration-files/Introduction.md b/docs/documentation/ko/declaration-files/Introduction.md new file mode 100644 index 00000000..3a6f1622 --- /dev/null +++ b/docs/documentation/ko/declaration-files/Introduction.md @@ -0,0 +1,56 @@ +--- +title: Introduction +layout: docs +permalink: /ko/docs/handbook/declaration-files/introduction.html +oneline: "How to write a high-quality TypeScript Declaration (d.ts) file" +--- + +이 가이드는 고품질의 TypeScript 선언 파일을 작성하는 방법을 알려주기 위해 작성되었습니다. + +이 가이드는, TypeScript 언어에 대한 기본 지식이 있다고 가정합니다. +만약 기본 지식이 없다면, [TypeScript 핸드북](/docs/handbook/basic-types.html)을 반드시 읽고 + 기본 개념, 특히 타입과 모듈에 익숙해져야 합니다. + +# 섹션 (Sections) + +이 가이드는 다음 섹션들로 구성됩니다. + +## 라이브러리 구조 (Library Structures) + +[라이브러리 구조](/docs/handbook/declaration-files/library-structures.html)는 일반적인 라이브러리 포맷과 각 포맷에 대한 올바른 선언 파일을 작성하는 방법에 대해 알려줍니다. +기존 파일을 수정하는 경우라면, 이 섹션을 읽으실 필요는 없습니다. +새로운 선언 파일을 작성해야 한다면 라이브러리의 포맷이 선언 파일 작성에 어떻게 영향을 미치는지 올바르게 이해하기 위해 반드시 읽어야 합니다. + +## 예제를 통해 (By Example) + +많은 경우, 기본 라이브러리 예제만 있을 때, 선언 파일을 작성해야 합니다. +[예제를 통해](/docs/handbook/declaration-files/by-example.html) 섹션은 많은 API 패턴들과 각 패턴들의 선언을 작성하는 방법을 보여줍니다. +이 가이드는 TypeScript의 모든 언어 구성에 아직 익숙하지 않은 TypeScript 초심자에 초점을 맞추고 있습니다. + +## 해야 할 것과 하지 말아야 할 것 ("Do"s and "Don't"s) + +선언 파일의 많은 실수들은 쉽게 피할 수 있습니다. +[해야 할 것과 하지 말아야 할 것](/docs/handbook/declaration-files/do-s-and-don-ts.html) 섹션은 흔한 오류들을 식별하고, + 감지하는 방법과, + 수정하는 방법을 설명합니다. +흔한 실수들을 피하기 위해 반드시 모두가 이 섹션을 읽어야 합니다. + +## 깊게 들어가기 (Deep Dive) + +선언 파일이 동작하는 메커니즘에 관심 있는 숙련된 사용자들에게, + [깊게 들어가기](/docs/handbook/declaration-files/deep-dive.html) 섹션은 선언 작성의 많은 고급 개념을 설명해 주고, + 이 개념들을 활용하여 깔끔하고 더 직관적인 선언 파일을 만드는 방법을 보여줍니다. + +## 템플릿 (Templates) + +[템플릿](/docs/handbook/declaration-files/templates.html)에서는 새로운 파일을 작성할 때, 유용한 시작점을 제공하는 + 여러 선언 파일들을 찾을 수 있습니다. +[라이브러리 구조](/docs/handbook/declaration-files/library-structures.html) 문서를 참고하여 어떤 템플릿 파일을 사용할지 알아보세요. + +## npm에 배포하기 (Publish to npm) + +[배포](/docs/handbook/declaration-files/publishing.html) 섹션은 선언 파일을 npm 패키지에 배포하는 방법과, 의존성 패키지를 관리하는 방법을 설명합니다. + +## 선언 파일을 찾고 설치하기 (Find and Install Declaration Files) + +JavaScript 라이브러리 사용자를 위해, [소비](/docs/handbook/declaration-files/consumption.html) 섹션은 해당 선언 파일을 찾고 설치하는 몇 가지 간단한 방법을 제공합니다. diff --git a/docs/documentation/ko/declaration-files/Library Structures.md b/docs/documentation/ko/declaration-files/Library Structures.md new file mode 100644 index 00000000..25fd4ebc --- /dev/null +++ b/docs/documentation/ko/declaration-files/Library Structures.md @@ -0,0 +1,333 @@ +--- +title: Library Structures +layout: docs +permalink: /ko/docs/handbook/declaration-files/library-structures.html +oneline: How to structure your d.ts files +--- + +# 개요 (Overview) + +일반적으로, 선언 파일을 *구조화*하는 방법은 라이브러리를 사용하는 방법에 따라 다릅니다. +JavaScript에서 사용할 라이브러리를 제공하는 방법은 여러 가지가 있고, 이에 맞추어 선언 파일을 작성해야 합니다. +이 가이드는 일반적인 라이브러리 패턴을 식별하는 방법과, 그 패턴에 상응하는 선언 파일을 작성하는 방법에 대해 다룹니다. + +주요 라이브러리 각각의 구조화 패턴 유형은 [템플릿](/docs/handbook/declaration-files/templates.html) 섹션에 있습니다. +이 템플릿으로 시작하면 더 빠르게 진행할 수 있습니다. + +# 라이브러리 종류 식별하기 (Identifying Kinds of Libraries) + +첫 번째로, TypeScript 선언 파일이 나타낼 수 있는 라이브러리 종류를 다뤄보겠습니다. +각 종류의 라이브러리를 *사용하는* 방법과, *작성하는* 방법, 그리고 실제 라이브러리들의 예제를 볼 것입니다. + +라이브러리의 구조를 식별하는 것은 선언 파일을 작성하는 첫 단계입니다. +*사용법*과 *코드*를 기반으로 구조를 식별하는 방법에 대한 힌트를 제공합니다. +라이브러리의 문서와 구성에 따라서, 어떤 건 다른 것보다 훨씬 쉬울 수 있습니다. +본인에게 더 편한 것을 사용할 것을 추천합니다. + +## 어떤 사항을 고려해야 하는가? (What should you look for?) + +라이브러리를 사용하기 전에, 다음 사항을 고려해 볼 수 있습니다. + +1. 라이브러리를 다운로드하는 방식이 무엇인가? + + 예를 들어, npm으로만 다운로드 할 수 있는가? 아니면 CDN 에서만 다운로드 할 수 있는가? + +2. 라이브러리를 임포트하는 방식이 무엇인가? + + 전역 객체를 추가하는 방식인가? 아니면 `require` 또는 `import`/`export` 구문을 사용하는 방식인가? + +## 여러 종류의 라이브러리에 대한 간단한 샘플 + +## 모듈형 라이브러리 (Modular Libraries) + +어떤 라이브러리는 모듈 로더 환경에서만 동작합니다. +예를 들어, `express`는 Node.js에서만 동작하고 반드시 CommonJS의 `require` 함수로 로드되어야 합니다. + +ECMAScript 2015 (ES2015, ECMAScript 6, ES6로도 잘 알려진), CommonJS와 RequireJS는 *모듈*을 *importing*하는 비슷한 개념을 가지고 있습니다. +JavaScript의 CommonJS (Node.js)를 예를 들면, 다음과 같이 작성합니다 + +```js +var fs = require("fs"); +``` + +TypeScript나 ES6에서는, `import` 키워드가 같은 목적을 제공합니다: + +```ts +import fs = require("fs"); +``` + +일반적으로 모듈형 라이브러리의 문서에서 다음 코드들 중 하나를 볼 수 있습니다: + +```js +var someLib = require('someLib'); +``` + +혹은 + +```js +define(..., ['someLib'], function(someLib) { + +}); +``` + +전역 모듈과 마찬가지로 UMD 모듈의 문서에서도 이 예제들을 볼 수 있으므로, 코드나 문서를 반드시 확인하세요. + +### 코드에서 모듈 라이브러리 식별하기 (Identifying a Module Library from Code) + +모듈형 라이브러리는 일반적으로 다음 중 몇 가지를 반드시 가지고 있습니다: + +* `require` 혹은 `define`에 대한 무조건적인 호출 +* `import * as a from 'b';` 혹은 `export c;` 같은 선언문 +* `exports` 혹은 `module.exports`에 대한 할당 + +다음은 거의 갖지 않습니다: + +* `window` 혹은 `global` 프로퍼티 할당 + +### 모듈을 위한 템플릿 (Templates For Modules) + +모듈을 위한 네 가지 템플릿이 있습니다. +- [`module.d.ts`](/docs/handbook/declaration-files/templates/module-d-ts.html) +- [`module-class.d.ts`](/docs/handbook/declaration-files/templates/module-class-d-ts.html) +- [`module-function.d.ts`](/docs/handbook/declaration-files/templates/module-function-d-ts.html) +- [`module-plugin.d.ts`](/docs/handbook/declaration-files/templates/module-plugin-d-ts.html) + +각각이 어떻게 동작하는지에 대한 개요는 [`module.d.ts`](/docs/handbook/declaration-files/templates/module-d-ts.html)를 참조하세요. + +만약 모듈을 함수처럼 *호출*할 수 있으면 [`module-function.d.ts`](/docs/handbook/declaration-files/templates/module-function-d-ts.html)을 사용하세요: + +```js +const x = require("foo"); +// 참고: 함수로 'x'를 호출 +const y = x(42); +``` + +만약 모듈이 `new`를 사용하여 *생성*될 수 있다면 [`module-class.d.ts`](/docs/handbook/declaration-files/templates/module-class-d-ts.html)를 사용하세요: + +```js +const x = require("bar"); +// 참고: 'new' 연산자를 import된 변수에 사용 +const y = new x("hello"); +``` + +임포트 되었을 때 다른 모듈에 수정사항을 만드는 모듈을 사용한다면, [`module-plugin.d.ts`](/docs/handbook/declaration-files/templates/module-plugin-d-ts.html) 템플릿을 사용하세요: + +```js +const jest = require("jest"); +require("jest-matchers-files"); +``` + +## 전역 라이브러리 (Global Libraries) + +*전역* 라이브러리는 전역 스코프 (즉, `import` 형식을 사용하지 않음)에서 접근 가능한 라이브러리입니다. +많은 라이브러리는 사용을 위해 간단히 하나 이상의 전역 변수를 노출합니다. +예를 들어, [jQuery](https://jquery.com/)를 사용한다면, `$` 변수를 참조해서 사용할 수 있습니다: + +```ts +$(() => { console.log('hello!'); } ); +``` + +HTML 스크립트 태그로 라이브러리를 사용하는 방법은 라이브러리 문서에서 지침을 볼 수 있습니다: + +```html + +``` + +오늘날, 대부분의 전역에서 접근 가능한 유명 라이브러리들은 실제로 UMD 라이브러리로 작성되어 있습니다 (아래를 참조). +UMD 라이브러리 문서는 전역 라이브러리 문서와 구별하기 어렵습니다. +전역 선언 파일을 작성하기 전에, 실제로는 UMD가 아닌지 확인하십시오. + +### 코드에서 전역 라이브러리 식별하기 (Identifying a Global Library from Code) + +전역 라이브러리 코드는 대게 엄청 간단합니다. +전역 "Hello, world" 라이브러리는 다음과 같습니다: + +```js +function createGreeting(s) { + return "Hello, " + s; +} +``` + +혹은 다음과 같습니다: + +```js +// Web +window.createGreeting = function (s) { + return "Hello, " + s; +}; + +// Node +global.createGreeting = function (s) { + return "Hello, " + s; +}; + +// Potentially any runtime +globalThis.createGreeting = function (s) { + return "Hello, " + s; +}; +``` + +전역 라이브러리의 코드를 보면, 보통 다음을 볼 수 있습니다: + +* 최상위 레벨 `var`문 이나 `function`선언 +* 하나 이상의 `window.someName` 할당 +* DOM 인터페이스 `document` 혹은 `window`가 존재한다고 가정 + +다음은 볼 수 *없습니다*: + +* `require` 이나 `define` 같은 모듈 로더 검사 혹은 사용 +* `var fs = require("fs");` 형태의 CommonJS/Node.js-스타일 import +* `define(...)` 호출 +* 라이브러리를 `require` 혹은 import하는 방법에 대해 설명하는 문서 + +### 전역 라이브러리 예제 (Examples of Global Libraries) + +전역 라이브러리를 UMD 라이브러리로 바꾸는게 쉽기 때문에, 전역 스타일로 작성한 인기 라이브러리는 거의 없습니다. +하지만, 크기가 작고 DOM이 필요한 (혹은 의존성이 *없는*) 라이브러리는 여전히 전역입니다. + +### 전역 라이브러리 템플릿 (Global Library Template) + +템플릿 파일 [`global.d.ts`](./templates/global.d.ts.md)은 예제 라이브러리 `myLib`를 정의합니다. +["이름 충돌 방지" 각주](#preventing-name-conflicts)를 반드시 읽어보세요. + +## *UMD* + +*UMD* 모듈은 모듈로 (import를 통해) 사용할 수 있고 혹은 전역으로도 (모듈 로더 없는 환경에서 실행될 때) 사용할 수 있습니다. +[Moment.js](http://momentjs.com/) 같은 많은 유명한 라이브러리들은 이 방법으로 작성되었습니다. +예를 들어, Node.js나 RequireJS를 사용하면, 다음과 같이 작성합니다: + +```ts +import moment = require("moment"); +console.log(moment.format()); +``` + +반면 바닐라 브라우저 환경에서는 다음과 같이 쓸 수 있습니다: + +```js +console.log(moment.format()); +``` + +### UMD 라이브러리 식별하기 (Identifying a UMD library) + +[UMD modules](https://github.com/umdjs/umd)은 모듈 로더 환경 유무를 검사합니다. +이는 다음과 같이 보이는 찾기 쉬운 패턴입니다: + +```js +(function (root, factory) { + if (typeof define === "function" && define.amd) { + define(["libName"], factory); + } else if (typeof module === "object" && module.exports) { + module.exports = factory(require("libName")); + } else { + root.returnExports = factory(root.libName); + } +}(this, function (b) { +``` + +만약 라이브러리 코드, 특히 파일 상단에서 `typeof define`, `typeof window` 혹은 `typeof module`에 대한 테스트를 보았다면, 거의 대부분 UMD 라이브러리입니다. + +UMD 라이브러리 문서에서는 `require`를 보여주는 "Node.js에서 사용하기" 예제를 종종 설명하고 + "브라우저에서 사용하기" 예제에서는 `