본문으둜 κ±΄λ„ˆλ›°κΈ°

πŸ‘‰ TypeScript

πŸ₯• νƒ€μž…κ³Ό μΈν„°νŽ˜μ΄μŠ€μ˜ 차이점​

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ λͺ…λͺ…λœ νƒ€μž…μ„ μ •μ˜ν•˜λŠ” 방법은 두 가지가 μžˆμŠ΅λ‹ˆλ‹€.

type TState = {
name: string;
capital: string;
}

interface IState {
name: string;
capital: string;
}

νƒ€μž…κ³Ό μΈν„°νŽ˜μ΄μŠ€ 사이에 μ‘΄μž¬ν•˜λŠ” 차이λ₯Ό λΆ„λͺ…ν•˜κ²Œ μ•Œκ³ , 같은 μƒν™©μ—μ„œλŠ” λ™μΌν•œ λ°©λ²•μœΌλ‘œ λͺ…λͺ…λœ νƒ€μž…μ„ μ •μ˜ν•΄ 일관성을 μœ μ§€ν•΄μ•Ό ν•©λ‹ˆλ‹€.

μΈν„°νŽ˜μ΄μŠ€ μ„ μ–Έκ³Ό νƒ€μž… μ„ μ–Έμ˜ λΉ„μŠ·ν•œ 점​

λͺ…λͺ…λœ νƒ€μž…μ€ μΈν„°νŽ˜μ΄μŠ€λ‘œ μ •μ˜ν•˜λ“  νƒ€μž…μœΌλ‘œ μ •μ˜ν•˜λ“  μƒνƒœμ—λŠ” 차이가 μ—†μŠ΅λ‹ˆλ‹€. λ§Œμ•½ IState와 TStateλ₯Ό μΆ”κ°€ 속성과 ν•¨κ»˜ ν• λ‹Ήν•œλ‹€λ©΄ λ™μΌν•œ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.

인덱슀 μ‹œκ·Έλ‹ˆμ²˜λŠ” μΈν„°νŽ˜μ΄μŠ€μ™€ νƒ€μž…μ—μ„œ λͺ¨λ‘ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

type TDict = {
[key: string]: string
};

interface IDict {
[key: string]: string;
}

λ˜ν•œ ν•¨μˆ˜ νƒ€μž…λ„ μΈν„°νŽ˜μ΄μŠ€λ‚˜ νƒ€μž…μœΌλ‘œ μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

type TFn = (x: number) => string;
interface IFn {
(x: number): string;
}

const toStrT: TFn = (x) => '' + x;
const toStrT: IFn = (x) => '' + x;

νƒ€μž… 별칭과 μΈν„°νŽ˜μ΄μŠ€λŠ” λͺ¨λ‘ μ œλ„ˆλ¦­μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.

type TPair<T> = {
first: T;
second: T;
}

interface IPair<T> {
first: T;
second: T;
}

μΈν„°νŽ˜μ΄μŠ€λŠ” νƒ€μž…μ„ ν™•μž₯ν•  수 있으며, νƒ€μž…μ€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό ν™•μž₯ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

interface IStateWithPop extends TState {
population: number;
}

type TStateWithPop = IState & { population: number; };

μ—¬κΈ°μ„œ μ£Όμ˜ν•  점은 μΈν„°νŽ˜μ΄μŠ€λŠ” μœ λ‹ˆμ˜¨ νƒ€μž… 같은 λ³΅μž‘ν•œ νƒ€μž…μ„ ν™•μž₯ν•˜μ§€ λͺ»ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. λ³΅μž‘ν•œ νƒ€μž…μ„ ν™•μž₯ν•˜κ³  μ‹Άλ‹€λ©΄ νƒ€μž…κ³Ό &λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.
ν•œνŽΈ 클래슀λ₯Ό κ΅¬ν˜„ν•  λ•ŒλŠ”, νƒ€μž…κ³Ό μΈν„°νŽ˜μ΄μŠ€ λ‘˜ λ‹€ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

class StateT implements TState {
name: string = '';
capital: string = '';
}

class StateI implements IState {
name: string = '';
capital: string = '';
}

μΈν„°νŽ˜μ΄μŠ€ μ„ μ–Έκ³Ό νƒ€μž… μ„ μ–Έμ˜ λ‹€λ₯Έ 점​

μœ λ‹ˆμ˜¨ νƒ€μž…μ€ μžˆμ§€λ§Œ μœ λ‹ˆμ˜¨ μΈν„°νŽ˜μ΄μŠ€λΌλŠ” κ°œλ…μ€ μ—†μŠ΅λ‹ˆλ‹€.

type AorB = 'a' | 'b';

μΈν„°νŽ˜μ΄μŠ€λŠ” νƒ€μž…μ„ ν™•μž₯ν•  수 μžˆμ§€λ§Œ, μœ λ‹ˆμ˜¨μ€ ν•  수 μ—†μŠ΅λ‹ˆλ‹€. 그런데 μœ λ‹ˆμ˜¨ νƒ€μž…μ„ ν™•μž₯ν•˜λŠ” 게 ν•„μš”ν•  λ•Œκ°€ μžˆμŠ΅λ‹ˆλ‹€.

type Input = { /* ... */};
type Output = { /* ... */};
interface VariableMap {
[name: string]: Input | Output;
}

λ˜λŠ” μœ λ‹ˆμ˜¨ νƒ€μž…μ— name 속성을 뢙인 νƒ€μž…μ„ λ§Œλ“€ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

type NamedVariable = (Input | Output) & { name: string };

이 νƒ€μž…μ€ μΈν„°νŽ˜μ΄μŠ€λ‘œ ν‘œν˜„ν•  수 μ—†μŠ΅λ‹ˆλ‹€. type ν‚€μ›Œλ“œλŠ” 일반적으둜 interface보닀 μ“°μž„μƒˆκ°€ λ§ŽμŠ΅λ‹ˆλ‹€. type ν‚€μ›Œλ“œλŠ” μœ λ‹ˆμ˜¨μ΄ 될 μˆ˜λ„ 있고, λ§€ν•‘λœ νƒ€μž… λ˜λŠ” 쑰건뢀 νƒ€μž… 같은 κ³ κΈ‰ κΈ°λŠ₯에 ν™œμš©λ˜κΈ°λ„ ν•©λ‹ˆλ‹€.
νŠœν”Œκ³Ό λ°°μ—΄ νƒ€μž…λ„ type ν‚€μ›Œλ“œλ₯Ό μ΄μš©ν•΄ 더 κ°„κ²°ν•˜κ²Œ ν‘œν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

type Pair = [number, number];
type StringList = string[];
type NamedNums = [string, ...number[]];

μΈν„°νŽ˜μ΄μŠ€λ‘œλ„ νŠœν”Œκ³Ό λΉ„μŠ·ν•˜κ²Œ κ΅¬ν˜„ν•  수 μžˆκΈ°λŠ” ν•©λ‹ˆλ‹€.

interface Tuple {
0: number;
1: number;
length: 2;
}
const t: Tuple = [10, 20]; // 정상

κ·ΈλŸ¬λ‚˜ μΈν„°νŽ˜μ΄μŠ€λ‘œ νŠœν”Œκ³Ό λΉ„μŠ·ν•˜κ²Œ κ΅¬ν˜„ν•˜λ©΄ νŠœν”Œμ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” concat 같은 λ©”μ„œλ“œλ“€μ„ μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ―€λ‘œ νŠœν”Œμ€ type ν‚€μ›Œλ“œλ‘œ κ΅¬ν˜„ν•˜λŠ” 것이 λ‚«μŠ΅λ‹ˆλ‹€.

반면 μΈν„°νŽ˜μ΄μŠ€λŠ” νƒ€μž…μ— μ—†λŠ” λͺ‡ 가지 κΈ°λŠ₯이 μžˆμŠ΅λ‹ˆλ‹€. 그쀑 ν•˜λ‚˜λ‘œ λ°”λ‘œ 보강(augment)이 κ°€λŠ₯ν•˜λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 이번 μ•„μ΄ν…œ μ²˜μŒμ— λ“±μž₯ν–ˆλ˜ State μ˜ˆμ œμ— population ν•„λ“œλ₯Ό μΆ”κ°€ν•  λ•Œ 보강 기법을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

interface IState {
name: string;
capital: string;
}

interface IState {
population: number;
}

const wyoming: IState = {
name: 'Wyoming',
capital: 'Cheyenne',
population: 500_000
}; // 정상

이 예제처럼 속성을 ν™•μž₯ν•˜λŠ” 것을 μ„ μ–Έ 병합(declaration merging)이라고 ν•©λ‹ˆλ‹€. μ„ μ–Έ 병합은 주둜 νƒ€μž… μ„ μ–Έ νŒŒμΌμ—μ„œ μ‚¬μš©λ©λ‹ˆλ‹€. λ”°λΌμ„œ νƒ€μž… μ„ μ–Έ νŒŒμΌμ„ μž‘μ„±ν•  λ•ŒλŠ” μ„ μ–Έ 병합을 μ§€μ›ν•˜κΈ° μœ„ν•΄ λ°˜λ“œμ‹œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•˜λ©° ν‘œμ€€μ„ 따라야 ν•©λ‹ˆλ‹€. νƒ€μž… μ„ μ–Έμ—λŠ” μ‚¬μš©μžκ°€ μ±„μ›Œμ•Ό ν•˜λŠ” λΉˆν‹ˆμ΄ μžˆμ„ 수 μžˆλŠ”λ°, λ°”λ‘œ 이 μ„ μ–Έ 병합이 κ·Έλ ‡μŠ΅λ‹ˆλ‹€.

병합은 μ„ μ–Έμ²˜λŸΌ 일반적인 μ½”λ“œλΌμ„œ μ–Έμ œλ“ μ§€ κ°€λŠ₯ν•˜λ‹€λŠ” 것을 μ•Œκ³  μžˆμ–΄μ•Όν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ―€λ‘œ ν”„λ‘œνΌν‹°κ°€ μΆ”κ°€λ˜λŠ” 것을 μ›ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ μΈν„°νŽ˜μ΄μŠ€ λŒ€μ‹  νƒ€μž…μ„ μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

정리​

이번 μ•„μ΄ν…œμ˜ 처음 질문으둜 λŒμ•„κ°€ νƒ€μž…κ³Ό μΈν„°νŽ˜μ΄μŠ€ 쀑 μ–΄λŠ 것을 μ‚¬μš©ν•΄μ•Ό 할지 결둠을 λ‚΄λ € λ³΄κ² μŠ΅λ‹ˆλ‹€. λ³΅μž‘ν•œ νƒ€μž…μ΄λΌλ©΄ κ³ λ―Όν•  것도 없이 νƒ€μž… 별칭을 μ‚¬μš©ν•˜λ©΄ λ©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ νƒ€μž…κ³Ό μΈν„°νŽ˜μ΄μŠ€, 두 가지 λ°©λ²•μœΌλ‘œ λͺ¨λ‘ ν‘œν˜„ν•  수 μžˆλŠ” κ°„λ‹¨ν•œ 객체 νƒ€μž…μ΄λΌλ©΄ 일관성과 λ³΄κ°•μ˜ κ΄€μ μ—μ„œ κ³ λ €ν•΄ 보야 ν•©λ‹ˆλ‹€. μ•Œκ΄€λ˜κ²Œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” μ½”λ“œλ² μ΄μŠ€μ—μ„œ μž‘μ—…ν•˜κ³  μžˆλ‹€λ©΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜κ³ , μΌκ΄€λ˜κ²Œ νƒ€μž…μ„ μ‚¬μš© 쀑이라면 νƒ€μž…μ„ μ‚¬μš©ν•˜λ©΄ λ©λ‹ˆλ‹€.
아직 μŠ€νƒ€μΌμ΄ ν™•λ¦½λ˜μ§€ μ•Šμ€ ν”„λ‘œμ νŠΈλΌλ©΄, ν–₯μš°μ— λ³΄κ°•μ˜ κ°€λŠ₯성이 μžˆμ„μ§€ 생각해 봐야 ν•©λ‹ˆλ‹€. μ–΄λ–€ API에 λŒ€ν•œ νƒ€μž… 선언을 μž‘μ„±ν•΄μ•Ό ν•œλ‹€λ©΄ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” 게 μ’‹μŠ΅λ‹ˆλ‹€. APIκ°€ 변경될 λ•Œ μ‚¬μš©μžκ°€ μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 μƒˆλ‘œμš΄ ν•„λ“œλ₯Ό 병합할 수 μžˆμ–΄ μœ μš©ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ ν”„λ‘œμ νŠΈ λ‚΄λΆ€μ μœΌλ‘œ μ‚¬μš©λ˜λŠ” νƒ€μž…μ— μ„ μ–Έ 병합이 λ°œμƒν•˜λŠ” 것은 잘λͺ»λœ μ„€κ³„μž…λ‹ˆλ‹€. λ”°λΌμ„œ 이럴 λ•ŒλŠ” νƒ€μž…μ„ μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

πŸ₯• μ—΄κ±°ν˜•(enum) μ‚¬μš©μ„ μ§€μ–‘ν•΄μ•Όν•˜λŠ” μ΄μœ β€‹

νƒ€μž…μŠ€ν¬λ¦½νŠΈκ°€ νƒœλ™ν•˜λ˜ 2010λ…„κ²½, μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 결함이 많고 κ°œμ„ ν•΄μ•Ό ν•  뢀뢄이 λ§Žμ€ μ–Έμ–΄μ˜€μŠ΅λ‹ˆλ‹€. 그리고 클래슀, λ°μ½”λ ˆμ΄ν„°, λͺ¨λ“ˆ μ‹œμŠ€ν…œ 같은 κΈ°λŠ₯이 μ—†μ–΄μ„œ ν”„λ ˆμž„μ›Œν¬λ‚˜ 트랜슀파일러둜 λ³΄μ™„ν•˜λŠ” 것이 일반적인 λͺ¨μŠ΅μ΄μ—ˆμŠ΅λ‹ˆλ‹€. κ·Έλ ‡κΈ° 떄문에 νƒ€μž…μŠ€ν¬λ¦½νŠΈλ„ 초기 λ²„μ „μ—λŠ” λ…λ¦½μ μœΌλ‘œ κ°œλ°œν•œ 클래슀, μ—΄κ±°ν˜•(enum), λͺ¨λ“ˆ μ‹œμŠ€ν…œμ„ ν¬ν•¨μ‹œν‚¬ μˆ˜λ°–μ— μ—†μ—ˆμŠ΅λ‹ˆλ‹€.

μ‹œκ°„μ΄ 흐λ₯΄λ©° TC39(μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό κ΄€μž₯ν•˜λŠ” ν‘œμ€€ 기ꡬ)λŠ” λΆ€μ‘±ν–ˆλ˜ 점듀을 λŒ€λΆ€λΆ„ λ‚΄μž₯ κΈ°λŠ₯으둜 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μžλ°”μŠ€ν¬λ¦½νŠΈμ— μƒˆλ‘œ μΆ”κ°€λœ κΈ°λŠ₯은 νƒ€μž…μŠ€ν¬λ¦½νŠΈ 초기 λ²„μ „μ—μ„œ λ…λ¦½μ μœΌλ‘œ κ°œλ°œν–ˆλ˜ κΈ°λŠ₯κ³Ό ν˜Έν™˜μ„± 문제λ₯Ό λ°œμƒμ‹œμΌ°μŠ΅λ‹ˆλ‹€. 그렇기에 νƒ€μž…μŠ€ν¬λ¦½νŠΈ μ§„μ˜μ—μ„œλŠ” λ‹€μŒ μ „λž΅ 쀑 ν•˜λ‚˜λ₯Ό 선택해야 ν–ˆμŠ΅λ‹ˆλ‹€. ν•œ 가지 μ „λž΅μ€ νƒ€μž…μŠ€ν¬λ¦½νŠΈ 초기 λ²„μ „μ˜ ν˜•νƒœλ₯Ό μœ μ§€ν•˜κΈ° μœ„ν•΄ μžλ°”μŠ€ν¬λ¦½νŠΈ μ‹ κ·œ κΈ°λŠ₯을 λ³€ν˜•ν•΄μ„œ λΌμ›Œ λ§žμΆ”λŠ” κ²ƒμž…λ‹ˆλ‹€. 또 λ‹€λ₯Έ μ „λž΅μ€ μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ μ‹ κ·œ κΈ°λŠ₯을 κ·ΈλŒ€λ‘œ μ±„νƒν•˜κ³  νƒ€μž…μŠ€ν¬λ¦½νŠΈ 초기 버전과 ν˜Έν™˜μ„±μ„ ν¬κΈ°ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

νƒ€μž…μŠ€ν¬λ¦½νŠΈ νŒ€μ€ λŒ€λΆ€λΆ„ 두 번쨰 μ „λž΅μ„ μ„ νƒν–ˆμŠ΅λ‹ˆλ‹€. κ²°κ΅­ TC39λŠ” λŸ°νƒ€μž„ κΈ°λŠ₯을 λ°œμ „μ‹œν‚€κ³ , νƒ€μž…μŠ€ν¬λ¦½νŠΈ νŒ€μ€ νƒ€μž… κΈ°λŠ₯만 λ°œμ „μ‹œν‚¨λ‹€λŠ” λͺ…ν™•ν•œ 원칙을 μ„Έμš°κ³  ν˜„μž¬κΉŒμ§€ μ§€μΌœμ˜€κ³  μžˆμŠ΅λ‹ˆλ‹€.

그런데 이 원칙이 μ„Έμ›Œμ§€κΈ° 전에, 이미 μ‚¬μš©λ˜κ³  있던 λͺ‡ 가지 κΈ°λŠ₯이 μžˆμŠ΅λ‹ˆλ‹€. 이 κΈ°λŠ₯듀은 νƒ€μž… 곡간(νƒ€μž…μŠ€ν¬λ¦½νŠΈ)κ³Ό κ°’ 곡간(μžλ°”μŠ€ν¬λ¦½νŠΈ)의 경계λ₯Ό ν˜Όλž€μŠ€λŸ½κ²Œ λ§Œλ“€κΈ° λ•Œλ¬Έμ— μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ„œλŠ” ν”Όν•΄μ•Ό ν•˜λŠ” κΈ°λŠ₯을 λͺ‡ 가지 μ‚΄νŽ΄λ΄…λ‹ˆλ‹€. 그리고 λΆˆκ°€ν”Όν•˜κ²Œ 이 κΈ°λŠ₯을 μ‚¬μš©ν•˜κ²Œ λ˜λŠ” 경우 μ–΄λ–€ 점에 μœ μ˜ν•΄μ•Ό ν˜Έν™˜μ„± 문제λ₯Ό μΌμœΌν‚€μ§€ μ•ŠλŠ”μ§€ μ•Œμ•„λ΄…λ‹ˆλ‹€.

μ—΄κ±°ν˜•(enum)​

λ§Žμ€ μ–Έμ–΄μ—μ„œ λͺ‡λͺ‡ κ°’μ˜ λͺ¨μŒμ„ λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ μ—΄κ±°ν˜•μ„ μ‚¬μš©ν•©λ‹ˆλ‹€. νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œλ„ μ—΄κ±°ν˜•μ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

enum Flavor {
VANILLA = 0,
CHOCOLATE = 1,
STRAWBERRY = 2,
}

let flavor = Flavor.CHOCOLATE; // νƒ€μž…μ΄ Flavor

Flavor // μžλ™μ™„μ„± μΆ”μ²œ: VANILLA, CHOCOLATE, STRAWBERRY
Flavor[0] // 값이 "VANILLA"

λ‹¨μˆœνžˆ 값을 λ‚˜μ—΄ν•˜λŠ” 것보닀 μ‹€μˆ˜κ°€ 적고 λͺ…ν™•ν•˜κΈ° λ•Œλ¬Έμ— 일반적으둜 μ—΄κ±°ν˜•μ„ μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ μ—΄κ±°ν˜•μ€ λͺ‡ 가지 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ μ—΄κ±°ν˜•μ€ λ‹€μŒ λͺ©λ‘μ²˜λŸΌ 상황에 따라 λ‹€λ₯΄κ²Œ λ™μž‘ν•©λ‹ˆλ‹€.

  • 숫자 μ—΄κ±°ν˜•(μ•ž 예제의 Flavor)에 0, 1, 2 μ™Έμ˜ λ‹€λ₯Έ μˆ«μžκ°€ ν• λ‹Ήλ˜λ©΄ 맀우 μœ„ν—˜ν•©λ‹ˆλ‹€. (이 방법은 μ›λž˜ λΉ„νŠΈ ν”Œλž˜κ·Έ ꡬ쑰λ₯Ό ν‘œν˜„ν•˜κΈ° μœ„ν•΄ μ„€κ³„λ˜μ—ˆμŠ΅λ‹ˆλ‹€.)
  • μƒμˆ˜ μ—΄κ±°ν˜•μ€ λ³΄ν†΅μ˜ μ—΄κ±°ν˜•κ³Ό 달리 λŸ°νƒ€μž„μ— μ™„μ „νžˆ μ œκ±°λ©λ‹ˆλ‹€. μ•žμ˜ 예제λ₯Ό const enum Flavor둜 λ°”κΎΈλ©΄, μ»΄νŒŒμΌλŸ¬λŠ” Flavor.CHOCOLATE을 1으둜 λ°”κΏ” λ²„λ¦½λ‹ˆλ‹€. 이런 κ²°κ³ΌλŠ” κΈ°λŒ€ν•˜μ§€ μ•Šμ€ 것이며, λ¬Έμžμ—΄ μ—΄κ±°ν˜•κ³Ό 숫자 μ—΄κ±°ν˜•κ³Ό μ „ν˜€ λ‹€λ₯Έ λ™μž‘μž…λ‹ˆλ‹€.
  • preserveConstEnums ν”Œλž˜κ·Έλ₯Ό μ„€μ •ν•œ μƒνƒœμ˜ μƒμˆ˜ μ—΄κ±°ν˜•μ€ λ³΄ν†΅μ˜ μ—΄κ±°ν˜•μ²˜λŸΌ λŸ°νƒ€μž„ μ½”λ“œμ— μƒμˆ˜ μ—΄κ±°ν˜• 정보λ₯Ό μœ μ§€ν•©λ‹ˆλ‹€.
  • λ¬Έμžμ—΄ μ—΄κ±°ν˜•μ€ λŸ°νƒ€μž„μ˜ νƒ€μž… μ•ˆμ „μ„±κ³Ό 투λͺ…성을 μ œκ³΅ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ λ‹€λ₯Έ νƒ€μž…κ³Ό 달리 ꡬ쑰적 타이핑이 μ•„λ‹Œ λͺ…λͺ©μ  타이핑을 μ‚¬μš©ν•©λ‹ˆλ‹€.

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ 일반적인 νƒ€μž…λ“€μ΄ ν• λ‹Ή κ°€λŠ₯성을 μ²΄ν¬ν•˜κΈ° μœ„ν•΄μ„œ ꡬ쑰적 타이핑을 μ‚¬μš©ν•˜λŠ” 반면, λ¬Έμžμ—΄ μ—΄κ±°ν˜•μ€ λͺ…λͺ©μ  타이핑을 μ‚¬μš©ν•©λ‹ˆλ‹€.

ꡬ쑰적 타이핑은 ꡬ쑰가 κ°™μœΌλ©΄ 할당이 ν—ˆμš©λ˜λŠ” 반면, λͺ…λͺ©μ  타이핑은 νƒ€μž…μ˜ 이름이 κ°™μ•„μ•Ό 할당이 ν—ˆμš©λ©λ‹ˆλ‹€.

enum Flavor {
VANILLA = 'vanilla',
CHOCOLATE = 'chocolate',
STRAWBERRY = 'strawberry',
}

let flavor = Flavor.CHOCOLATE; // νƒ€μž…μ΄ Flavor
flavor = 'strawberry';
// ~~~~~ '"strawberry"' ν˜•μ‹μ€ 'Flavor' ν˜•μ‹μ— ν• λ‹Ήν•  수 μ—†μŠ΅λ‹ˆλ‹€.ts(2322)

λͺ…λͺ©μ  타이핑은 라이브러리λ₯Ό κ³΅κ°œν•  λ•Œ ν•„μš”ν•©λ‹ˆλ‹€. Flavorλ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ λ°›λŠ” ν•¨μˆ˜λ₯Ό κ°€μ •ν•΄ λ΄…μ‹œλ‹€.

function scoop(flavor: Flavor) { /* ... */ }

FlavorλŠ” λŸ°νƒ€μž„ μ‹œμ μ—λŠ” λ¬Έμžμ—΄μ΄κΈ° 떄문에, μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ λ‹€μŒμ²˜λŸΌ ν˜ΈμΆ”ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

scoop('vanilla'); // μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” 정상

κ·ΈλŸ¬λ‚˜ νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” μ—΄κ±°ν˜•μ„ μž„ν¬νŠΈν•˜κ³  λ¬Έμžμ—΄ λŒ€μ‹  μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

import { Flavor } from 'ice-cream';
scoop(Flavor.VANILLA);

이처럼 μžλ°”μŠ€ν¬λ¦½νŠΈμ™€ νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ λ™μž‘μ΄ λ‹€λ₯΄κΈ° λ•Œλ¬Έμ— λ¬Έμžμ—΄ μ—΄κ±°ν˜•μ€ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. μ—΄κ±°ν˜• λŒ€μ‹  λ¦¬ν„°λŸ΄ νƒ€μž…μ˜ μœ λ‹ˆμ˜¨μ„ μ‚¬μš©ν•˜λ©΄ λ©λ‹ˆλ‹€.

type Flavor = 'vanilla' | 'chocolate' | 'strawberry';

let flavor: Flavor = 'chocolate'; // 정상

λ¦¬ν„°λŸ΄ νƒ€μž…μ˜ μœ λ‹ˆμ˜¨μ€ μ—΄κ±°ν˜•λ§ŒνΌ μ•ˆμ „ν•˜λ©° μžλ°”μŠ€ν¬λ¦½νŠΈμ™€ ν˜Έν™˜λ˜λŠ” μž₯점이 μžˆμŠ΅λ‹ˆλ‹€. 그리고 νŽΈμ§‘κΈ°μ—μ„œ μ—΄κ±°ν˜•μ²˜λŸΌ μžλ™μ™„μ„± κΈ°λŠ₯을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ₯• any와 unknown의 차이​

unknown νƒ€μž…μ€ any νƒ€μž… μ™Έμ˜ μ–΄λ–€ νƒ€μž…μ—λ„ ν• λ‹Ήν•  수 μ—†λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 반면 anyλŠ” neverλ₯Ό μ œμ™Έν•œ λͺ¨λ“ κ²ƒμ— ν• λ‹Ή κ°€λŠ₯ν•©λ‹ˆλ‹€.

// error: boolean νƒ€μž…μ—λŠ” unknown νƒ€μž…μ„ ν• λ‹Ήν•  수 μ—†μŒ.
let unknownType: unknown;
let booleanType: boolean = unknownType;

// λ°˜λŒ€λ‘œ unknown νƒ€μž…μ— boolean νƒ€μž…μ„ ν• λ‹Ήν•˜λŠ” 건 κ°€λŠ₯.
let boolType: boolean = true;
let unknownType: unknown = boolType;

unknown νƒ€μž…μ—λŠ” μ–΄λ–€ 것을 λŒ€μž…ν•˜λŠ” 것이 μœ νš¨ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— any νƒ€μž…λ³΄λ‹€ λ”μš± μ•ˆμ „ν•©λ‹ˆλ‹€.
unknown νƒ€μž…μ€ ν”„λ‘œνΌν‹°μ— μ ‘κ·Ό, λ©”μ†Œλ“œ 호좜, μΈμŠ€ν„΄μŠ€ 생성을 ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

// anyλŠ” stringμ΄λΌλŠ” 보μž₯이 μ•„λ‹ˆμ—¬λ„ 호좜 κ°€λŠ₯.
let anyValue: any;
anyValue.toUpperCase();

// error: unknown은 λΆˆκ°€λŠ₯.
let unknownValue: unknown;
unknownValue.toUpperCase();

이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œλŠ” unknown νƒ€μž…μ„ string으둜 μ’ν˜€μ£Όμ–΄μ•Όν•©λ‹ˆλ‹€.

const unknownArgFunction = (value: unknown) => {
if (typeof value === 'string') {
// string으둜 νƒ€μž…μ„ μ’ν˜€μ€€ λ’€ λ©”μ„œλ“œλ₯Ό 호좜.
value.toUpperCase();
}
}

νƒ€μž…μŠ€ν¬λ¦½νŠΈλ₯Ό μ‚¬μš©ν•˜λ‹€λ³΄λ©΄ λ“€μ–΄μ˜€κ²Œ 될 인자의 νƒ€μž…μ„ μ˜ˆμΈ‘ν•  수 μ—†λŠ” κ²½μš°κ°€ μžˆλŠ”λ°, any νƒ€μž…μ„ μ‚¬μš©ν• λ•Œμ—λŠ” νœ΄λ¨Όμ—λŸ¬λ₯Ό λ°œμƒν•˜μ‹œ μ‰½μ§€λ§Œ, unknown νƒ€μž…μ€ 항상 νƒ€μž…μ„ λ¨Όμ € 확인 ν•œ 후에 무언가λ₯Ό μ‹œλ„ν•  수 있기 λ•Œλ¬Έμ— any νƒ€μž…λ³΄λ‹€ λ”μš± μ•ˆμ „ν•©λ‹ˆλ‹€.