any 와 unknown
타입 검사를 끄는 것과, 확인하기 전에는 사용하지 못하게 하는 것입니다.
무엇이든 담기는 두 가지
무엇이 담길지 미리 알 수 없는 자리가 있습니다. 서버에서 받은 값, 남이 만든 라이브러리가 돌려주는 값이 그렇습니다. 그런 자리를 위한 타입이 둘 있고, 둘의 차이가 큽니다.
any | unknown | |
|---|---|---|
| 담기는 것 | 무엇이든 | 무엇이든 |
| 그 값을 사용할 때 | 검사하지 않습니다 | 확인하기 전에는 못 씁니다 |
| 쓰임 | 급할 때 잠깐. 되도록 피합니다 | 밖에서 들어오는 값 |
any 는 검사를 끕니다
let value: any = "홍길동"; console.log(value.toUpperCase()); value = 27; console.log(value.toUpperCase());
타입 오류가 하나도 나지 않았습니다. 그대로 실행되었고, 숫자에서
toUpperCase 를 부르는 순간 멈췄습니다 — TypeScript 를
쓰기 전과 똑같습니다.
any 를 적으면 그 자리에서 타입 검사가 꺼집니다.
그것이 any 의 뜻입니다.
unknown 은 확인을 요구합니다
let value: unknown = "홍길동"; console.log(value.toUpperCase());
글자를 넣어 두었는데도 막혔습니다. unknown 은
무엇인지 확인하기 전에는 아무것도 할 수 없는 타입입니다.
let value: unknown = "홍길동"; if (typeof value === "string") { console.log(value.toUpperCase()); } console.log("끝");
typeof 로 확인한 안쪽에서는
string 으로 좁혀져 사용할 수 있습니다. 이것이
any 와의 결정적인 차이입니다 —
unknown 은 확인을 강제하고,
any 는 확인하지 않아도 지나갑니다.
어디에 무엇을 사용하나
JSON 을 되돌린 값은 실제로 무엇이 들었는지 알 수 없습니다. 그런 자리가
unknown 의 자리입니다.
// 서버가 무엇을 돌려줄지 코드는 모릅니다. const data: unknown = JSON.parse(text); if (typeof data === "object" && data !== null) { // 여기서부터 다룹니다 }
any 를 아예 쓰지 말라는 것은 아닙니다. JavaScript 로
된 코드를 TypeScript 로 옮기는 동안(4.2), 아직 타입을 붙이지 못한 자리를 잠시
막아 두는 데 사용합니다. 다만 남겨 두면 그 자리는 검사되지 않습니다.
처음에 자주 걸리는 것
오류를 없애는 가장 빠른 방법이지만, 없애는 것이 아니라 안 보이게 하는 것입니다. 그 자리는 실행할 때 터집니다.
any 인 값에서 꺼낸 것도
any 입니다. 한 자리에 두면 그 값이 지나가는
모든 곳에서 검사가 꺼집니다.
함수 매개 변수에 타입을 적지 않으면 추론할 것이 없어
any 가 됩니다. 설정에서
noImplicitAny 로 막습니다(4.1).
직접 해보기
unknown 을 받아 숫자면
"숫자 27", 글자면
"글자 홍길동", 그 밖이면
"모르는 값" 을 돌려주는 함수를 만드세요.
function describe(value: unknown): string {
if (typeof value === "number") return `숫자 ${value}`;
if (typeof value === "string") return `글자 ${value}`;
return "모르는 값";
}
console.log(describe(27));
console.log(describe("홍길동"));
console.log(describe(true));
위 함수의 unknown 을
any 로 바꾸면 무엇이 달라지는지 확인하세요.
unknown 은 그때 오류를 내고, any 는 그대로 지나갑니다.이 단원의 정리
any는 그 자리의 타입 검사를 끕니다.unknown은 무엇인지 확인해야 사용할 수 있습니다.- 밖에서 들어오는 값에는
unknown을 사용합니다. any는 옮아가서 검사되지 않는 자리를 넓힙니다.- 매개 변수에 타입을 적지 않으면
any가 됩니다.