Skip to content

Latest commit

Β 

History

History
231 lines (173 loc) Β· 7.98 KB

File metadata and controls

231 lines (173 loc) Β· 7.98 KB

μ •μ˜ 파일 이둠: 심측 뢄석 (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을 μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€:

export var SomeVar: { a: SomeType };
export interface SomeType {
  count: number;
}

κ·Έ λ‹€μŒ μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€:

import * as foo from './foo';
let x: foo.SomeType = foo.SomeVar.a;
console.log(x.count);

잘 μž‘λ™ν•˜μ§€λ§Œ, SomeTypeκ³Ό SomeVarλŠ” 이름이 같도둝 λ°€μ ‘ν•˜κ²Œ κ΄€λ ¨λ˜μ–΄ μžˆλ‹€κ³  상상할 수 μžˆμŠ΅λ‹ˆλ‹€. 결합을 μ‚¬μš©ν•˜μ—¬ 같은 이름 Bar둜 두 가지 λ‹€λ₯Έ 객체 (κ°’κ³Ό νƒ€μž…)λ₯Ό ν‘œμ‹œ ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

export var Bar: { a: Bar };
export interface Bar {
  count: number;
}

이 경우 μ‚¬μš©ν•˜λŠ” μ½”λ“œλ₯Ό ꡬ쑰 λΆ„ν•΄ν•  수 μžˆλŠ” μ•„μ£Ό 쒋은 κΈ°νšŒμž…λ‹ˆλ‹€:

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)

μΈν„°νŽ˜μ΄μŠ€μ— λ‹€λ₯Έ μΈν„°νŽ˜μ΄μŠ€ 선언을 μ‚¬μš©ν•˜μ—¬ 멀버λ₯Ό μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

interface Foo {
  x: number;
}
// ... λ‹€λ₯Έ μœ„μΉ˜ ...
interface Foo {
  y: number;
}
let a: Foo = ...;
console.log(a.x + a.y); // 성곡

ν΄λž˜μŠ€μ™€λ„ 같이 λ™μž‘ν•©λ‹ˆλ‹€:

class Foo {
  x: number;
}
// ... λ‹€λ₯Έ μœ„μΉ˜ ...
interface Foo {
  y: number;
}
let a: Foo = ...;
console.log(a.x + a.y); // 성곡

단, νƒ€μž… 별칭 (type s = string;)μ—λŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•΄μ„œ μΆ”κ°€ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜μ—¬ μΆ”κ°€ν•˜κΈ° (Adding using a namespace)

λ„€μž„μŠ€νŽ˜μ΄μŠ€ 선언은 μΆ©λŒμ„ μΌμœΌν‚€μ§€ μ•ŠλŠ” λ°©μ‹μœΌλ‘œ μƒˆλ‘œμš΄ νƒ€μž…, κ°’ 그리고 λ„€μž„μŠ€νŽ˜μ΄μŠ€λ₯Ό μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, ν΄λž˜μŠ€μ— 정적 멀버λ₯Ό μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

class C {
}
// ... λ‹€λ₯Έ μœ„μΉ˜ ...
namespace C {
  export let x: number;
}
let y = C.x; // 성곡

μœ„ μ˜ˆμ œμ—μ„œ C의 정적 μΈ‘λ©΄(μƒμ„±μž ν•¨μˆ˜)에 값을 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€. 값을 μΆ”κ°€ ν–ˆκ³  λͺ¨λ“  값에 λŒ€ν•œ μ»¨ν…Œμ΄λ„ˆκ°€ λ‹€λ₯΄κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. (νƒ€μž…μ€ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— ν¬ν•¨λ˜κ³  λ„€μž„μŠ€νŽ˜μ΄μŠ€λŠ” λ‹€λ₯Έ λ„€μž„μŠ€νŽ˜μ΄μŠ€μ— ν¬ν•¨λ©λ‹ˆλ‹€).

λ„€μž„μŠ€νŽ˜μ΄μŠ€ νƒ€μž…μ„ ν΄λž˜μŠ€μ— μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

class C {
}
// ... λ‹€λ₯Έ μœ„μΉ˜ ...
namespace C {
  export interface D { }
}
let y: C.D; // 성곡

이 μ˜ˆμ œμ—μ„œ namespace 선언을 μž‘μ„±ν•  λ•ŒκΉŒμ§€ λ„€μž„μŠ€νŽ˜μ΄μŠ€ CλŠ” μ—†μ—ˆμŠ΅λ‹ˆλ‹€. λ„€μž„μŠ€νŽ˜μ΄μŠ€ CλŠ” ν΄λž˜μŠ€μ— μ˜ν•΄ μƒμ„±λœ C의 κ°’ λ˜λŠ” νƒ€μž…κ³Ό μΆ©λŒν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ§ˆμ§€λ§‰μœΌλ‘œ namespace 선언을 μ‚¬μš©ν•˜μ—¬ λ‹€μ–‘ν•œ 병합을 ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 특히 ν˜„μ‹€μ μΈ μ˜ˆλŠ” μ•„λ‹ˆμ§€λ§Œ, ν₯미둜운 λ™μž‘μ„ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€:

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 선언이 λŒ€μƒμ˜ λͺ¨λ“  의미 λ₯Ό λ‚΄λ³΄λ‚΄κ±°λ‚˜ κ°€μ Έμ˜¨λ‹€λŠ” 것 μž…λ‹ˆλ‹€.