๋ฐ˜์‘ํ˜•

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ NOT ! ์—ฐ์‚ฐ์ž๋Š” false๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋ฐ˜๋ฉด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„  ์ด ๋Š๋‚Œํ‘œ ! ์—ฐ์‚ฐ์ž๊ฐ€ ๋ณ€์ˆ˜ ๋’ค์— ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. if๋ฌธ ๋“ฑ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ํ•ญ์ƒ ์œ ํšจํ•œ ๊ฐ’์ด ์žˆ๋‹ค๊ณ  ๋‹จ์–ธ ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

Non-null assertion operator (๋Š๋‚Œํ‘œ)


๐Ÿ’ก ESLint ๊ทœ์น™์—์„  ๋Š๋‚Œํ‘œ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด null-checking mode์˜ ํ˜œํƒ์„ ๋ฐ›์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ถŒ์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋Œ€์‹  foo.bar && foo.bar... AND ์—ฐ์‚ฐ์ž ํ˜น์€ ์˜ต์…”๋„ ์ฒด์ด๋‹ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•œ๋‹ค. ๋Š๋‚Œํ‘œ ์—ฐ์‚ฐ์ž๋ฅผ ๊ผญ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋ฉด ํ•ญ์ƒ ์œ ํšจํ•œ ๊ฐ’์„ ๋ณด์žฅํ•˜๋Š” ๋ณ€์ˆ˜์—๋งŒ ์‚ฌ์šฉํ•œ๋‹ค.

 

๋ณ€์ˆ˜ ๋‚ด๋ถ€ ๊ฐ’์— ์ ‘๊ทผํ•  ๋•Œ TS ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ํ•ญ์ƒ null undefined ์ธ์ง€ ์ฒดํฌํ•œ๋‹ค. ์ด๋•Œ if ๋ฌธ์œผ๋กœ ํƒ€์ž… ๋‹จ์–ธ์„(๋ณ€์ˆ˜์— ์›ํ•˜๋Š” ํƒ€์ž…์„ ๊ฐ•์ œ๋กœ ๋ถ€์—ฌ)์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋งค๋ฒˆ if ๋ฌธ ์“ฐ๋Š”๊ฒŒ ๊ท€์ฐฎ์„ ๋•Œ ! ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿผ ํ•ด๋‹น ๊ฐ’์ด null์ด๋‚˜ undefined๊ฐ€ ์•„๋‹ˆ๋ผ๊ณ  ๋‹จ์–ธํ•ด์ค€๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ์ด ๊ฐ’์€ ์ ˆ๋Œ€ null ํ˜น์€ undefined๊ฐ€ ๋  ์ˆ˜ ์—†์œผ๋‹ˆ ์‹คํ–‰ํ•˜๋ผ๋Š” ๊ฒƒ๊ณผ ๋น„์Šทํ•˜๋‹ค.

 

์•„๋ž˜ ์ฝ”๋“œ์˜ ์ฝ˜์†”์„ ์‹คํ–‰ํ•˜๋ฉด TS2531 ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. lastName ํƒ€์ž…์„ string ํ˜น์€ null๋กœ ์„ค์ •ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๊ฐ’์ด null์ผ ์ˆ˜๋„ ์žˆ์–ด์„œ ๋‚˜์˜ค๋Š” ๊ฒฝ๊ณ ๋‹ค.

interface User {
  firstName: string;
  lastName: string | null;
}

const user1: User = {
  firstName: 'Cobain',
  lastName: 'Kurt',
};

console.log(user1.lastName.toUpperCase());
// ์—๋Ÿฌ! TS2531: Object is possibly 'null'.

 

์•„๋ž˜์ฒ˜๋Ÿผ lastName ๋’ค์— ! ๋Š๋‚Œํ‘œ๋ฅผ ๋ถ™์—ฌ์„œ ํ•ญ์ƒ ๊ฐ’์ด ์กด์žฌํ•œ๋‹ค๊ณ  ๋‹จ์–ธํ•˜๋ฉด ์—๋Ÿฌ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค.

console.log(user1.lastName!.toUpperCase()); // 'Kurt'

 

์ด์™€ ๋น„์Šทํ•œ ์˜ต์…”๋„ ์ฒด์ด๋‹(๋ณ€์ˆ˜๋’ค์— ๋ฌผ์Œํ‘œ ? ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ)์€ ํ•ด๋‹น ๊ฐ’์ด null ํ˜น์€ undefined๋ฉด ํ‰๊ฐ€๋ฅผ ๋ฉˆ์ถ”๊ณ  undefined ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ ์ด ๋‹ค๋ฅด๋‹ค. ์•„๋ž˜์ฒ˜๋Ÿผ ํ‰๊ฐ€ํ•˜๋Š” ๊ฐ’์ด null์ด๋‚˜ undefined์ผ ์ˆ˜๋„ ์žˆ์„ ๋• ์—๋Ÿฌ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์˜ต์…”๋„ ์ฒด์ด๋‹์„ ์‚ฌ์šฉํ•œ๋‹ค.

const user1: ServiceUser = {
  firstName: 'Cobain',
  lastName: null,
};

console.log(user1.lastName!.toUpperCase()); // ์—๋Ÿฌ! Cannot read properties of null (reading 'toUpperCase')
console.log(user1.lastName?.toUpperCase()); // undefined

 

Definite assignment assertions


๋ณ€์ˆ˜ ๋’ค์— ๋Š๋‚Œํ‘œ ์—ฐ์‚ฐ์ž !๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ’์ด ํ• ๋‹น๋˜์–ด ์žˆ์ง€ ์•Š์€ ๋ณ€์ˆ˜๋‚˜ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ํ•ด๋‹น ๋ณ€์ˆ˜์˜ ๊ฐ’์€ ํ•ญ์ƒ ํ• ๋‹น๋˜์–ด ์žˆ๋‹ค๊ณ (์•„์ง ๊ฐ’์„ ํ• ๋‹นํ•˜์ง€ ์•Š์•˜์–ด๋„) ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์ด๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค. ์ด๋ฅผ Definite Assignment Assertions ๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. 

 

์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ ๊ฐ’์„ ํ• ๋‹นํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์šฉํ•˜๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ TS2454 ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

let num: number;
console.log(num); // ์—๋Ÿฌ! TS2454: Variable 'num' is used before being assigned.

 

num ๋ณ€์ˆ˜ ๋’ค์— ๋Š๋‚Œํ‘œ !๋ฅผ ๋ถ™์ด๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ๋ณ€์ˆ˜ num์€ ํ•ญ์ƒ ๊ฐ’์ด ํ• ๋‹น๋˜์–ด ์žˆ๋‹ค๊ณ  ๋‹จ์–ธ(assertion)ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

let num!: number;
console.log(num); // undefined

 

์•„๋ž˜์ฒ˜๋Ÿผ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋Š๋‚Œํ‘œ ์—ฐ์‚ฐ์ž๋ฅผ ๋ถ™์—ฌ์„œ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

let num: number;
console.log(num!); // undefined

 


๊ธ€ ์ˆ˜์ •์‚ฌํ•ญ์€ ๋…ธ์…˜ ํŽ˜์ด์ง€์— ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”
๋ฐ˜์‘ํ˜•