0%

JavaScript말고 TypeScript써야 하는이유 : Null 과 Undefined

typescript

Javascript에서의 변수는 처음에 초기화 되기 전 undefined 형식입니다.
어떤 변수는 개발자가 null 로 지정한 후
뒤에서 if (someObject === null) { someObject = a; } 이렇게 초기화를 하기도 합니다.

하지만 늘 생각대로 코딩이 되지는 않습니다.
초기화 될 줄 알았던 코드는 초기화가 안될 수 있고
객체가 반환되리라 예상했던 부분에서는 제대로 반환이 안될 수 있습니다.

예를 들어 아래와 같은 javascript 코드를 살펴보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
async function getPerson() {
const [row] = await conn.execute("SELECT ... ") // 여기서 문제가 발생했다면?
return {
name: row[0].name,
age: row[0].age,
address: row[0].address,
}
}

async main() {
const person = await getPersonInfo(); // 제대로된 결과가 리턴되지 않았을 것입니다.
if (person.age > 20) { // person.age 에는 제대로 된 값이 있을까요?
doSomeLogic();
}
}

이 코드를 보면 main() 함수의 person 변수에
.age 라는 속성이 확실하게 있는 것인지 알 수 없습니다.
어쩌면 undefined 값일지도 모릅니다.
혹은, person 변수 자체가 undefined 일 수도 있습니다.
이럴 경우 어떻게 보완해 볼 수 있을까요?
JavaScript 에서도 아래처럼 보완해 볼 수는 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
async function getPerson() {
const [row] = await conn.execute("SELECT ... ") // 여기서 문제가 발생했다면?
return {
name: row[0].name || "Unknown", // 값이 없어도 이제 "Unknown" 을 반환
age: row[0].age || 0, // 기본값으로 0 지정
address: row[0].address || "None", // 기본으로 "None" 반환
}
}

async main() {
const person = await getPerson(); // 제대로된 결과가 리턴되지 않았을 것입니다.
if (person.age > 20) { // person.age 에는 최소한 0 혹은 제대로 된 값이 있을 것입니다.
doSomeLogic();
}
}

하지만 뭔가 깔끔하지 않아 보입니다.
person 변수가 뭔가 값을 가지고 있는지 아닌지, 나중에는 확신이 들지 않을 수도 있기 때문입니다.
이런 걱정을 미연에 방지하기 위해, TypeScript는 아래처럼 작성할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
async function getPerson(): Promise<Person> {
const person: Person = { // 미리 반환할 객체 타입을 초기화
name: "Unknown",
age: 0,
address: "None",
}
const [row] = await connection.execute("SELECT ... ") // 여기서 문제가 발생했다면?
if (row[0]) { // 여기로 들어오지 않는다!
person.name = row[0].name
person.age = row[0].age
person.address = row[0].address
}
return person; // 이제 getPerson 는 무조건 Person 타입의 값을 반환함
}

async main() {
const person: Person = await getPerson() // null 이나 undefined 일 수가 없습니다!
if (person.age > 20) { // person.age 에는 최소한 0 혹은 제대로 된 값이 있을 것입니다.!
doSomeLogic();
}
}

뭔가 미묘한 차이로 보이지만, JavaScript 대비 훨씬 안정적으로 변했습니다.
person 변수는 이제 null 혹은 undefined 일 수가 없습니다.
무조건 Person 타입의 객체임을 보장할 수 있습니다.
물론 JavaScript로도 비슷하게 가능하지만, TypeScript 만큼 명료하고 깔끔하게 코드 작성하기는 어렵습니다.

TypeScript에서는 리턴 값이 null 일 수도 있다면 Person | null 이런 식으로 명시를 해줘야 합니다.
이 경우, 리턴을 받는 값을 이용하여 .age 처럼 프로퍼티에 액세스 하려면 똑똑한 IDE가
“null 일수도 있는데 이렇게 바로 쓰면 안된다” 하고 알려줍니다.
코드를 처음부터 런타임 에러가 발생하지 않도록 방어적으로 잘 작성할 수 있게 도와주는 것입니다.
그래서 TypeScript 가 더욱 유용합니다.