TypeScript νƒ€μž…: any, unknown, never

2023. 3. 9. 00:11ㆍ언어/Javascript(Node, TS...)

TypeScriptμ—μ„œ νƒ€μž…λ“€μ€ νŠΉμ • λ³€μˆ˜κ°€ κ°€μ§ˆ 수 μžˆλŠ” κ°’μ˜ λ²”μœ„λ‘œ λ³Ό 수 μžˆλ‹€.

TypeScriptμ—λŠ” λ‹€μ–‘ν•œ νƒ€μž…λ“€μ΄ μ‘΄μž¬ν•˜λŠ”λ°,

이번 κΈ€μ—μ„œλŠ” κ·Έ 쀑 any, unknown, never에 λŒ€ν•΄ 닀뀄보렀고 ν•œλ‹€. 

 

Type: any

any νƒ€μž…μ€ νƒ€μž… κ³„μ˜ 전체 μ§‘ν•©μœΌλ‘œ,

any νƒ€μž…μ΄ λ°”μΈλ”©λœ λ³€μˆ˜μ—λŠ” κ·Έ μ–΄λ–€ 값도 λ“€μ–΄κ°ˆ 수 μžˆλ‹€. 

μ—¬κΈ°μ„œ λλ‚˜λ©΄ μ’‹κ² μ§€λ§Œ, 끝이 μ•„λ‹ˆλ‹€.

any νƒ€μž…μ΄ λ°”μΈλ”©λœ λ³€μˆ˜κ°€ κ·Έ 이후에 λ‘œμ§μ—μ„œ μ‚¬μš©λ  λ•Œ, μ»΄νŒŒμΌλŸ¬λŠ” μ–΄λ–€ νƒ€μž… 검사도 μš”κ΅¬ν•˜μ§€ μ•Šκ³  μ»΄νŒŒμΌλ§ν•œλ‹€.

즉 JavaScriptμ—μ„œμ˜ λ³€μˆ˜λ₯Ό μƒμ„±ν•œ 것과 λ™μΌν•˜κ²Œ 여겨지고 ν•΄λ‹Ή λ³€μˆ˜λ₯Ό 가지고 μ–΄λ–€ 일이든 ν•  수 μžˆλ‹€.

λ‹€λ§Œ, κ·Έ ν–‰μœ„μ˜ κ²°κ³ΌλŠ” λŸ°νƒ€μž„μ—μ„œ μ‹€μ œ μž‘λ™ν•˜κΈ° μ „κΉŒμ§€λŠ” μ•Œ 수 μ—†λ‹€.

λ”°λΌμ„œ anyλ₯Ό μ΄μš©ν•˜μ—¬ λ‘œμ§μ„ μž‘μ„±ν•˜κ²Œ 되면

κ²°κ³Όλ₯Ό μ˜ˆμƒν•˜κΈ° νž˜λ“  μ½”λ“œκ°€ 되고 μ½”λ“œμ˜ μ•ˆμ „μ„±μ΄ 떨어지며, 이둜 인해 버그가 창ꢐ할 κ°€λŠ₯성이 높아진닀.

λ‹€λ§Œ λ‘œμ§μ„ μž‘μ„±ν•˜λ‹€λ³΄λ©΄ λŸ°νƒ€μž„μ—μ„œ λ³€μˆ˜μ˜ νƒ€μž…μ΄ κ²°μ •λ˜λŠ” κ²½μš°κ°€ μ’…μ’… 있고

이λ₯Ό μœ„ν•΄ any와 같이 일단 λͺ¨λ“  νƒ€μž…μ„ 담을 그릇은 ν•„μš”ν•˜κΈ° λ§ˆλ ¨μ΄λ‹€.

μ•„λž˜λŠ” any νƒ€μž…μ˜ μ‚¬μš© μ˜ˆμ‹œμ΄λ‹€.

const anyObject: any = {'a':1, 'b':"c"};

// νƒ€μž… 검사λ₯Ό ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— ν•΄λ‹Ή λ‘œμ§μ€ 문제 없이 컴파일되고, λŸ°νƒ€μž„μ—μ„œ undefinedλ₯Ό λ°˜ν™˜.
console.log(anyObject.c);

// ν•΄λ‹Ή μ½”λ“œλŠ” number와 string κ°„μ˜ κ³±μ…ˆ 연산이기 λ•Œλ¬Έμ— λŸ°νƒ€μž„μ—μ„œ μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚€λŠ” μ½”λ“œμ΄μ§€λ§Œ,
// anyObjectκ°€ any νƒ€μž…μ΄κΈ° λ•Œλ¬Έμ— νƒ€μž… 검사λ₯Ό μ§„ν–‰ν•˜μ§€ μ•Šκ³  μ΄ν•˜μ˜ ν”„λ‘œνΌν‹°λ₯Ό λͺ¨λ‘ any νƒ€μž…μœΌλ‘œ λ‘” 채 컴파일 μˆ˜ν–‰
console.log(anyObject.a * anyObject.b);

 

Type: unknown

μœ„ 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ 이후 μΆ”κ°€λœ νƒ€μž…μ΄ λ°”λ‘œ unknown이닀.

unknown νƒ€μž…μ€ any νƒ€μž…κ³Ό μœ μ‚¬ν•˜κ²Œ, λͺ¨λ“  νƒ€μž…μ˜ λ³€μˆ˜λ“€μ„ 담을 수 μžˆλŠ” TypeScript 3.0μ—μ„œ μƒˆλ‘­κ²Œ μΆ”κ°€λœ νƒ€μž…μ΄λ‹€.

unknown νƒ€μž…κ³Ό any νƒ€μž…μ€ λ‹€λ§Œ λ³€μˆ˜ ν• λ‹Ή 이후가 λ‹¬λΌμ§€λŠ”λ°,

λ³€μˆ˜ ν• λ‹Ή 이후 ν•΄λ‹Ή λ³€μˆ˜λ₯Ό 가지고 μ–΄λ–€ λ‘œμ§μ„ κ΅¬μ„±ν•˜λ”λΌλ„ 컴파일 νƒ€μž„μ—μ„œλŠ” νƒ€μž… 검사λ₯Ό μš”κ΅¬ν•˜μ§€ μ•ŠλŠ” any νƒ€μž…κ³Ό 달리

unknown νƒ€μž…μ€ ν• λ‹Ή 이후 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄ λ‘œμ§μ— μ ν•©ν•œ νƒ€μž…μ„ ν•΄λ‹Ή λ³€μˆ˜κ°€ 가지고 μžˆλŠ”μ§€ 좔가적인 검사λ₯Ό μš”κ΅¬ν•˜κ²Œ λœλ‹€.

검사 없이 λ‘œμ§μ„ μž‘μ„±ν•˜κ²Œ 되면, μ»΄νŒŒμΌλŸ¬λŠ” κ³§λ°”λ‘œ μ—λŸ¬λ₯Ό λ‚΄λ±‰λŠ”λ‹€.

λ”°λΌμ„œ any νƒ€μž…μ—μ„œ λ¬Έμ œκ°€ λ˜μ—ˆλ˜ 뢀뢄듀을 unknown νƒ€μž…μ΄ κ°€λ €μ€€λ‹€.

μ•„λž˜λŠ” unknown νƒ€μž…μ˜ μ‚¬μš© μ˜ˆμ‹œμ΄λ‹€.

const num: unknown = 10;

// μ•„λž˜ μ½”λ“œλŠ” unknown νƒ€μž…μ˜ νŠΉμ„± 상 컴파일 μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚€κ³  νƒ€μž… 검사λ₯Ό μš”κ΅¬λ°›μŒ 
console.log(num+10);

// νƒ€μž… 검사λ₯Ό μˆ˜ν–‰ν•˜μ—¬ num λ³€μˆ˜μ˜ νƒ€μž…μ„ number λ²”μœ„κΉŒμ§€ ν•œμ •ν–ˆκΈ° λ•Œλ¬Έμ— 잘 μž‘λ™
if (typeof num === "number") {
  console.log(num+10);
}

any νƒ€μž…μ˜ 쑴재 이유?

unknown νƒ€μž…μ΄ any νƒ€μž…μ˜ 단점을 잘 κ°€λ €μ£ΌκΈ° λ•Œλ¬Έμ—, any νƒ€μž…μ΄ μ™œ μ•„μ§κΉŒμ§€ TypeScript λͺ…세에 λ‚¨μ•„μžˆλŠ”μ§€ κΆκΈˆν•  수 μžˆλ‹€.

ν•˜μ§€λ§Œ any νƒ€μž…λ„ λΆ„λͺ… μ“°μž„μƒˆκ°€ μžˆλ‹€.

λ§Œμ•½ μ™ΈλΆ€ λΌμ΄λΈŒλŸ¬λ¦¬λ‘œλΆ€ν„° 데이터λ₯Ό κ°€μ Έμ˜¨ λ’€ 이λ₯Ό 파일둜 μ €μž₯ν•΄μ•Όν•œλ‹€κ³  ν–ˆμ„ λ•Œ,

ν•΄λ‹Ή λ°μ΄ν„°μ˜ νƒ€μž…μ— λŒ€ν•œ 정보λ₯Ό 얻을 길이 μ „ν˜€ μ—†λ‹€λ©΄ μ–΄λ–¨κΉŒ?

unknown νƒ€μž…μ„ μ΄μš©ν•˜λ € 해도, 데이터가 μ–΄λ–€ μ–΄λ–€ νŠΉμ„±μ„ κ°–λŠ”μ§€ μ „ν˜€ μ•Œ 수 μ—†κΈ° λ•Œλ¬Έμ— νƒ€μž… κ°€λ“œλ₯Ό μΆ”κ°€ν•  수 μ—†λ‹€. 

λ”°λΌμ„œ ν•΄λ‹Ή κ²½μš°μ—λŠ” μ–΄μ©” 수 없이 any νƒ€μž…μ„ μ΄μš©ν•΄μ•Ό ν•œλ‹€.

 

Type: never

μ•žμ„œ any νƒ€μž…μ΄ νƒ€μž… κ³„μ˜ 전체 집합이라면, never νƒ€μž…μ€ 곡집합이닀.

never νƒ€μž…μ€ TypeScript의 λ°”λ‹₯ νƒ€μž…μœΌλ‘œλ„ λΆˆλ¦¬λŠ”λ°,

κ³΅μ§‘ν•©μ΄λΌλŠ” λΉ„μœ λŒ€λ‘œ μ–΄λ–€ νƒ€μž…λ„ (심지어 undefinedκΉŒμ§€λ„!) never νƒ€μž…μ— 바인딩될 수 μ—†λ‹€.

이게 무슨 μ˜λ―Έμ΄λƒλ©΄, κ·Έ μ–΄λ–€ 값도 λ©”λͺ¨λ¦¬μ— 할당될 수 μ—†κΈ° λ•Œλ¬Έμ— λ°œμƒ μžμ²΄κ°€ μ•ˆν•˜λŠ” κ²ƒμœΌλ‘œ λ³Ό 수 μžˆλ‹€.

never νƒ€μž…μ„ κ°–λŠ” ν•¨μˆ˜μ˜ μ˜ˆμ‹œλŠ” λ‹€μŒμ΄ μ‘΄μž¬ν•œλ‹€.

// neverλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜
// λ”°λΌμ„œ μ œμ–΄κΆŒμ΄ ν˜ΈμΆœλΆ€λ‘œ μ΄λ™ν•˜μ§€ μ•Šκ³  ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ κ³§λ°”λ‘œ ν”„λ‘œμ„ΈμŠ€λ₯Ό μ’…λ£Œμ‹œν‚΄.
process.exit(0);

// 항상 μ—λŸ¬λ₯Ό λ˜μ§€λŠ” ν•¨μˆ˜μ΄κΈ° λ•Œλ¬Έμ— λ°˜ν™˜κ°’μ΄ x
function alwaysThrowError():never {
  throw new Error();
}

// λ¬΄ν•œλ£¨ν”„λ‘œ 인해 ν•¨μˆ˜κ°€ μ ˆλŒ€ λ°˜ν™˜λ˜μ§€ μ•ŠμŒ
function infiniteLoop():never {
  while (true) {
    console.log("-");
  }
}

  never vs void

μžμΉ«ν•˜λ©΄ never νƒ€μž…κ³Ό void νƒ€μž…μ„ ν˜Όλ™ν•  수 μžˆλ‹€.

ν•˜μ§€λ§Œ 이 λ‘˜μ€ μ„œλ‘œ μ™„μ „νžˆ λ‹€λ₯΄λ‹€.

일반적으둜 voidλ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜λŠ” λ°˜ν™˜κ°’μ΄ μ—†λŠ” κ²ƒμœΌλ‘œ λ³΄μ΄μ§€λ§Œ, 싀은 μ»΄νŒŒμΌλŸ¬κ°€ 자체적으둜 return undefinedλ₯Ό ν•˜λ„λ‘ μˆ˜μ •ν•œλ‹€.

즉, void νƒ€μž…μ—λŠ” undefined 값이 할당될 수 μžˆλŠ” 것이닀. (섀정에 λ”°λΌμ„œλŠ” null 값도 할당이 κ°€λŠ₯ν•˜λ‹€.)

반면 neverλŠ” μ•žμ„œ μ–ΈκΈ‰ν–ˆλ“―μ΄ λ°”λ‹₯νƒ€μž…μ΄λ©° νƒ€μž…μ˜ 곡집합이닀.

λ”°λΌμ„œ undefined 쑰차도 할당이 λΆˆκ°€λŠ₯ν•˜κ³ , ν•¨μˆ˜μ˜ κ²½μš°μ—λŠ” μ•„μ˜ˆ λ°˜ν™˜μ΄ λΆˆκ°€λŠ₯ν•˜λ‹€. 

 

 

μ°Έμ‘°

https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type

https://stackoverflow.com/questions/37910669/what-is-the-difference-between-never-and-void-in-typescript

https://ui.toast.com/posts/ko_20220323

 

Documentation - Everyday Types

The language primitives.

www.typescriptlang.org

 

Documentation - TypeScript 3.0

TypeScript 3.0 Release Notes

www.typescriptlang.org

 

What is the difference between never and void in typescript?

I have read this, but it is unclear what would be the difference between 'never' and 'void' type?

stackoverflow.com

 

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ Never νƒ€μž… μ™„λ²½ κ°€μ΄λ“œ

νƒ€μž…μŠ€ν¬λ¦½νŠΈμ˜ never νƒ€μž…μ€ λ‹€λ₯Έ νƒ€μž…λ§ŒνΌ ν”ν•˜κ²Œ μ‚¬μš©λ˜κ±°λ‚˜ ν”Όν•  수 μ—†λŠ” 것이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— μΆ©λΆ„νžˆ λ…Όμ˜λ˜κ³  μžˆμ§€ μ•Šλ‹€. νƒ€μž…μŠ€ν¬λ¦½νŠΈ μ΄ˆλ³΄μžλŠ” 쑰건뢀 νƒ€μž… 같은 κ³ κΈ‰ νƒ€μž…μ„ μ²˜λ¦¬ν•˜κ±°λ‚˜

ui.toast.com

 

'μ–Έμ–΄ > Javascript(Node, TS...)' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

Interface vs Abstract Class (in Typescript)  (0) 2023.03.19
Interface in TS (vs Java)  (0) 2023.03.19
NodeJS Child_process의 spawn(), exec(), fork()  (0) 2023.03.05