Function

μžλ°”μŠ€ν¬λ¦½νŠΈ ν”„λ‘œκ·Έλž¨μ—μ„œ κ°€μž₯ 핡심적인 역할을 μ°¨μ§€ν•˜λŠ” ν•¨μˆ˜ νƒ€μž…μ΄ νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œ μ–΄λ–»κ²Œ ν‘œν˜„λ˜λŠ”μ§€ 닀룬닀.

ν•¨μˆ˜μ˜ νƒ€μž…

ν•¨μˆ˜μ˜ νƒ€μž…μ„ κ²°μ •ν•˜κΈ° μœ„ν•΄μ„œλŠ” λ‹€μŒ 두 κ°€μ§€ 정보가 ν•„μš”ν•˜λ‹€.
  • λ§€κ°œλ³€μˆ˜(parameter)의 νƒ€μž…
  • λ°˜ν™˜κ°’(return value)의 νƒ€μž… (λ°˜ν™˜ νƒ€μž…)
λ§€κ°œλ³€μˆ˜μ˜ 경우, λ³€μˆ˜μ˜ νƒ€μž…μ„ ν‘œκΈ°ν•  λ•Œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ λ§€κ°œλ³€μˆ˜ 뒀에 콜둠(:)을 뢙이고 νƒ€μž…μ„ μ λŠ”λ‹€. (param1: number)
λ°˜ν™˜ νƒ€μž…μ€ λ§€κ°œλ³€μˆ˜ λͺ©λ‘μ„ λ‹«λŠ” κ΄„ν˜Έ())와 ν•¨μˆ˜ 본문을 μ—¬λŠ” μ—¬λŠ” λŒ€κ΄„ν˜Έ({) 사이에 μ½œλ‘ μ„ 뢙이고 ν‘œκΈ°ν•œλ‹€. (function (): number { ... })
예λ₯Ό λ“€μ–΄ 두 숫자λ₯Ό λ°›μ•„ κ·Έ 합을 λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λŠ” λ‹€μŒκ³Ό 같이 νƒ€μž… ν‘œκΈ°ν•œλ‹€.
function sum(a: number, b: number): number { return (a + b); }
λ§Œμ•½ ν•¨μˆ˜κ°€ μ•„λ¬΄λŸ° 값도 λ°˜ν™˜ν•˜μ§€ μ•Šκ³  μ’…λ£Œλœλ‹€λ©΄ λ°˜ν™˜ νƒ€μž…μœΌλ‘œ void λ₯Ό μ‚¬μš©ν•œλ‹€.
function logGreetings(name: string): void { console.log(`Hello, ${name}!`); }
void λ°˜ν™˜ νƒ€μž…μ„ κ°–λŠ” ν•¨μˆ˜κ°€ undefinedλ‚˜ null μ΄μ™Έμ˜ 값을 λ°˜ν™˜ν•˜λ©΄ νƒ€μž… μ—λŸ¬κ°€ λ°œμƒν•œλ‹€. voidκ°€ μ•„λ‹Œ λ°˜ν™˜ νƒ€μž…μ„ κ°–λŠ” ν•¨μˆ˜κ°€ 아무 값도 λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ” κ²½μš°λ„ λ§ˆμ°¬κ°€μ§€λ‹€.
function notReallyVoid(): void { return 1; } // error TS2322: Type '1' is not assignable to type 'void'. function actuallyVoid(): number { } // error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.

ν•¨μˆ˜ κ°’μ˜ νƒ€μž… ν‘œκΈ°

ν•¨μˆ˜ νƒ€μž…μ˜ 값에 νƒ€μž… ν‘œκΈ°λ₯Ό 뢙이기 μœ„ν•΄μ„œλŠ” ν™”μ‚΄ν‘œ ν•¨μˆ˜ μ •μ˜ 문법과 λΉ„μŠ·ν•œ 문법을 μ‚¬μš©ν•œλ‹€.
(...λ§€κ°œλ³€μˆ˜ λ‚˜μ—΄) => λ°˜ν™˜ νƒ€μž…
λ§€κ°œλ³€μˆ˜κ°€ μ—†λŠ” ν•¨μˆ˜μ˜ 경우 λ§€κ°œλ³€μˆ˜λ₯Ό μƒλž΅ν•΄ μ•„λž˜μ™€ 같이 μ λŠ”λ‹€.
() => λ°˜ν™˜ νƒ€μž…
μ˜ˆμ‹œλ₯Ό 듀어보면 μ•„λž˜μ™€ κ°™λ‹€. ν™”μ‚΄ν‘œ ν•¨μˆ˜ 문법을 μ‚¬μš©ν•œ ν•¨μˆ˜ λ˜ν•œ λΉ„μŠ·ν•˜κ²Œ μ •μ˜ κ°€λŠ₯ν•˜λ‹€.
const yetAnotherSum: (a: number, b: number) => number = sum; const onePlusOne: () => number = () => 2; const arrowSum: (a: number, b: number) => number = (a, b) => (a + b);
νƒ€μž… 별칭 λ˜ν•œ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.
type SumFunction = (a: number, b: number) => number; const definitelySum: SumFunction = (a, b) => (a + b);

κΈ°λ³Έ λ§€κ°œλ³€μˆ˜

ES6와 λ§ˆμ°¬κ°€μ§€λ‘œ, νƒ€μž…μŠ€ν¬λ¦½νŠΈμ—μ„œλ„ κΈ°λ³Έ λ§€κ°œλ³€μˆ˜ 문법을 μ‚¬μš©ν•  수 μžˆλ‹€. 이 λ•Œ 기본값은
λ§€κ°œλ³€μˆ˜λͺ…: νƒ€μž… = κΈ°λ³Έκ°’
function greetings(name: string = 'stranger'): void { console.log(`Hello, ${name}`); } greetings('Heejong'); // Hello, Heejong! greetings(); // Hello, stranger!

선택 λ§€κ°œλ³€μˆ˜

λ§Žμ€ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λŠ” ν•¨μˆ˜ μ •μ˜μ— λͺ…μ‹œλœ λ§€κ°œλ³€μˆ˜μ˜ μˆ˜λ³΄λ‹€ λ§Žκ±°λ‚˜ 적은 수의 μΈμžκ°€ λ“€μ–΄μ˜¨ 경우 μ—λŸ¬λ₯Ό λ±‰λŠ”λ‹€.
ν•œνŽΈ, μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 더 λ“€μ–΄μ˜¨ μΈμžλŠ” 버리고, 덜 λ“€μ–΄μ˜¨ μΈμžλŠ” undefinedκ°€ λ“€μ–΄μ˜¨ 것과 λ™μΌν•˜κ²Œ μ·¨κΈ‰ν•œ ν›„ μ–΄λ–»κ²Œλ“  ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λ € μ‹œλ„ν•œλ‹€.
이런 μ–Έμ–΄μ˜ νŠΉμ„± 및 κΈ°μ‘΄ μ‚¬μš©λ‘€λ₯Ό ν¬μš©ν•˜λ©΄μ„œ νƒ€μž… μ•ˆμ •μ„±μ„ ν™•λ³΄ν•˜κΈ° μœ„ν•΄ νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” 선택 λ§€κ°œλ³€μˆ˜λ₯Ό μ§€μ›ν•œλ‹€.
ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜ 이름 뒀에 λ¬ΌμŒν‘œ(?) 기호λ₯Ό λΆ™μ—¬ ν•΄λ‹Ή λ§€κ°œλ³€μˆ˜κ°€ μƒλž΅ 될 수 μžˆμŒμ„ λͺ…μ‹œν•  수 μžˆλ‹€. 예λ₯Ό λ“€μ–΄, optional?: number 둜 μ„ μ–Έλœ 선택 λ§€κ°œλ³€μˆ˜ optionalλ₯Ό ν•¨μˆ˜ λ³Έλ¬Έμ—μ„œ number νƒ€μž… κ°’μœΌλ‘œ μ‚¬μš©ν•˜λ €λ©΄ ν•΄λ‹Ή 값이 undefinedκ°€ μ•„λ‹Œμ§€λ₯Ό λ¨Όμ € 검사해야 ν•œλ‹€.
function fetchVideo(url: string, subtitleLanguage?: string) { const option = { url }; if (subtitleLanguage) { option.subtitleLanguage = true; } /* ... */ } fetchVideo('https://example.com', 'ko'); // okay fetchVideo('https://example.com'); // also okay
이 λ•Œ λ§€κ°œλ³€μˆ˜ μ •μ˜ μˆœμ„œμ—μ„œ 선택 λ§€κ°œλ³€μˆ˜ 이후에 ν•„μˆ˜ λ§€κ°œλ³€μˆ˜λ₯Ό λ‘λŠ” 것은 ν—ˆμš©λ˜μ§€ μ•ŠλŠ”λ‹€.
function invalidFetchVideo(subtitleUrl?: string, url: string) { /* ... */ } //error TS1016: A required parameter cannot follow an optional parameter.
μ΄λŸ¬ν•œ μ œμ•½μ΄ μ‘΄μž¬ν•˜λŠ” μ΄μœ λŠ” λ§Œμ•½ ν•„μˆ˜ λ§€κ°œλ³€μˆ˜κ°€ 선택 λ§€κ°œλ³€μˆ˜ 뒀에 μžˆμ„ μ‹œ, μΈμžκ°€ μ–΄λ–€ λ§€κ°œλ³€μˆ˜μ˜ 값인지 ꡬ뢄할 수 μ—†κΈ° λ•Œλ¬Έμ΄λ‹€.
예λ₯Ό λ“€μ–΄ μœ„μ˜ 두 ν•¨μˆ˜λ₯Ό μ•„λž˜μ™€ 같이 ν˜ΈμΆœν•˜λŠ” 경우λ₯Ό μƒκ°ν•΄λ³΄μž.
fetchVideo('https://example.com'); invalidFetchVideo('https://example.com');
이 λ•Œ 첫 번째 호좜의 경우 μΈμžκ°€ url λ§€κ°œλ³€μˆ˜μ˜ κ°’μ΄λΌλŠ” 것이 λͺ…λ°±ν•˜λ‹€.
ν•œνŽΈ 두 번째 ν˜ΈμΆœμ—μ„œλŠ” 'https://example.com' μ΄λΌλŠ” 값이 μ„ νƒλ§€κ°œλ³€μˆ˜μΈ subtitleUrl의 κ°’μœΌλ‘œ 쓰인건지, λ˜λŠ” url의 κ°’μœΌλ‘œ 쓰인 건지 λͺ¨ν˜Έν•˜λ‹€.
λ”°λΌμ„œ νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” 이런 μ‹μ˜ ν•¨μˆ˜ μ •μ˜λ₯Ό λ§Œλ‚˜λ©΄ 였λ₯˜λ₯Ό λ°œμƒμ‹œν‚¨λ‹€.

ν•¨μˆ˜ μ˜€λ²„λ‘œλ”©

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” ν•œ ν•¨μˆ˜κ°€ μ—¬λŸ¬ 쌍의 λ§€κ°œλ³€μˆ˜-λ°˜ν™˜ νƒ€μž… μŒμ„ κ°–λŠ” κ²½μš°κ°€ 맀우 ν”ν•˜λ‹€.
이런 ν•¨μˆ˜μ˜ νƒ€μž…μ„ μ •μ˜ν•  수 있게 ν•˜κ³ μž νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” ν•¨μˆ˜ μ˜€λ²„λ‘œλ”©(function overloading)을 μ§€μ›ν•œλ‹€.
νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ ν•¨μˆ˜ μ˜€λ²„λ‘œλ”©μ€ λ‹€μŒκ³Ό 같은 νŠΉμ§•μ„ κ°–λŠ”λ‹€.
  • ν•¨μˆ˜λŠ” ν•˜λ‚˜ μ΄μƒμ˜ νƒ€μž… μ‹œκ·Έλ‹ˆμ²˜λ₯Ό κ°€μ§ˆ 수 μžˆλ‹€.
  • ν•¨μˆ˜λŠ” 단 ν•˜λ‚˜μ˜ κ΅¬ν˜„μ„ κ°€μ§ˆ 수 μžˆλ‹€.
즉, μ˜€λ²„λ‘œλ”©μ„ ν†΅ν•΄μ„œ μ—¬λŸ¬ ν˜•νƒœμ˜ ν•¨μˆ˜ νƒ€μž…μ„ μ •μ˜ν•  수 μžˆμ§€λ§Œ, μ‹€μ œ κ΅¬ν˜„μ€ ν•œ 번만 κ°€λŠ₯ν•˜λ―€λ‘œ μ—¬λŸ¬ κ²½μš°μ— λŒ€ν•œ λΆ„κΈ°λŠ” ν•¨μˆ˜ λ³Έλ¬Έ λ‚΄μ—μ„œ 이루어져야 ν•œλ‹€
예λ₯Ό λ“€μ–΄ λ‹€μŒ ν•¨μˆ˜λ“€μ„ 보자.
function doubleString(str: string): string { return `${str}${str}`; } function doubleNumber(num: number): number { return (num * 2); } function doubleBooleanArray(arr: boolean[]): boolean[] { return arr.concat(arr); }
이 ν•¨μˆ˜λ“€μ€ 각각 λ¬Έμžμ—΄, 숫자, 그리고 λΆˆλ¦¬μ–Έμ˜ 배열을 λ°›μ•„ 두 배둜 λ§Œλ“œλŠ” ν•¨μˆ˜λ‹€.
이 λ•Œ, β€˜λ‘ 배’가 μ˜λ―Έν•˜λŠ” 건 νƒ€μž…μ— 따라 λ‹€λ₯΄κ³ , μ„Έ ν•¨μˆ˜λŠ” 인풋 νƒ€μž…μ— 따라 λ‹€λ₯Έ νƒ€μž…μ˜ 값을 λ°˜ν™˜ν•œλ‹€.
이 μ„Έ ν•¨μˆ˜λ₯Ό ν•¨μˆ˜ μ˜€λ²„λ‘œλ”©μ„ μ‚¬μš©ν•΄μ„œ ν•˜λ‚˜μ˜ double μ΄λΌλŠ” ν•¨μˆ˜λ‘œ ν•©μ³λ³΄μž.
λ¨Όμ € 각 경우의 νƒ€μž… μ‹œκ·Έλ‹ˆμ³λ₯Ό μ •μ˜ν•œλ‹€. νƒ€μž… μ‹œκ·Έλ‹ˆμ³λŠ” ν•¨μˆ˜ μ •μ˜μ™€ λ™μΌν•˜λ˜, 본문이 μƒλž΅λœ ν˜•νƒœλ‹€.
function double(str: string): string; function double(num: number): number; function double(arr: boolean[]): boolean[]; function double(arg) { if (typeof arg === 'string') { return `${arg}${arg}`; } else if (typeof arg === 'number') { return arg * 2; } else if (Array.isArray(arg)) { return arg.concat(arg); } } const num = double(3); // number const str = double('ab'); // string const arr = double([true, false]); // boolean[]
μ΄λ ‡κ²Œ μ˜€λ²„λ‘œλ”©μ„ 톡해 μ •μ˜λœ double ν•¨μˆ˜λŠ” ν˜ΈμΆœν•˜λŠ” 인자의 νƒ€μž…μ— 따라 λ°˜ν™˜ νƒ€μž…μ΄ 달라진닀.

This νƒ€μž…

μ•žμ„œ 2μž₯μ—μ„œ μ–ΈκΈ‰ν–ˆμ§€λ§Œ, μžλ°”μŠ€ν¬λ¦½νŠΈ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œμ˜ this 값은 ν•¨μˆ˜κ°€ μ •μ˜λ˜λŠ” μ‹œμ μ΄ μ•„λ‹Œ μ‹€ν–‰λ˜λŠ” μ‹œμ μ— κ²°μ •λœλ‹€.
이런 νŠΉμ„±μ€ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ this 의 νƒ€μž…μ„ μΆ”λ‘ ν•˜λŠ” 일을 맀우 μ–΄λ ΅κ²Œ λ§Œλ“ λ‹€.
νƒ€μž…μŠ€ν¬λ¦½νŠΈλŠ” 이런 어렀움을 ν•΄κ²°ν•˜κΈ° μœ„ν•΄ ν•¨μˆ˜ λ‚΄μ—μ„œμ˜ this νƒ€μž…μ„ λͺ…μ‹œν•  수 μžˆλŠ” μˆ˜λ‹¨μ„ μ œκ³΅ν•œλ‹€.
ν•¨μˆ˜μ˜ this νƒ€μž…μ„ λͺ…μ‹œν•˜κΈ° μœ„ν•΄μ„  ν•¨μˆ˜μ˜ νƒ€μž… μ‹œκ·Έλ‹ˆμ³μ—μ„œ λ§€κ°œλ³€μˆ˜ κ°€μž₯ μ•žμ— this λ₯Ό μΆ”κ°€ν•΄μ•Ό ν•œλ‹€.
이 λ•Œ this νƒ€μž…μ€ νƒ€μž… μ‹œμŠ€ν…œμ„ μœ„ν•΄μ„œλ§Œ μ‘΄μž¬ν•˜λŠ” μΌμ’…μ˜ κ°€μ§œ νƒ€μž…μ΄λ‹€.
즉, this λ§€κ°œλ³€μˆ˜λ₯Ό μΆ”κ°€ν•œλ‹€κ³  해도 ν•¨μˆ˜κ°€ λ°›λŠ” 인자 μˆ˜μ™€ 같은 μ‹€μ œ λ™μž‘μ€ λ³€ν•˜μ§€ μ•ŠλŠ”λ‹€.
interface HTMLElement { tagName: string; /* ... */ } interface Handler { (this: HTMLElement, event: Event, callback: () => void): void; } let cb: any; // μ‹€μ œ ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜μ—λŠ” thisκ°€ λ‚˜νƒ€λ‚˜μ§€ μ•ŠμŒ const onClick: Handler = function(event, cb) { // thisλŠ” HTMLElement νƒ€μž… console.log(this.tagName); cb(); }
λ§Œμ•½ this의 νƒ€μž…μ„ void둜 λͺ…μ‹œν•œλ‹€λ©΄ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ this에 μ ‘κ·Όν•˜λŠ” 일 자체λ₯Ό 막을 수 μžˆλ‹€.
interface NoThis { (this: void): void; } const noThis: NoThis = function() { console.log(this.a); // Property 'a' does not exist on type 'void'. }
// κ°•μ˜ μ½”λ“œ function add(n1: number, n2: number) { return n1 + n2; } function printResult(num: number): void { console.log('Result: ' + num); } function addAndHandle(n1: number, n2: number, cb: (num: number) => void) { const result = n1 + n2; cb(result); } printResult(add(5, 12)); let combineValues: (a: number, b: number) => number; combineValues = add; // combineValues = printResult; // combineValues = 5; console.log(combineValues(8, 8)); // let someValue: undefined; addAndHandle(10, 20, (result) => { console.log(result) });
Β