프론트엔드 개발자라면 누구나 악명 높은 _"함수가 아닙니다"라는 메시지가 뜨는 좌절감을 잘 알고 있습니다. 이 메시지는 코드가 목표를 달성할 수 있어도 일관성이나 신뢰성을 보장할 수 없다는 사실을 상기시켜 줍니다. 엄격한 타이핑 없이는 커피 부족이나 잠 부족으로 인한 작은 실수를 막을 수 없습니다.
자신의 인간성 외에도 다른 개발자들의 서투름이 있습니다. 서드파티 라이브러리는 파괴적인 변경사항을 도입해 재미를 더했습니다. 그 변수는 어디서, 어떻게 전달되나요? 무엇이 우연히 잘 되고 무엇이 신비롭게 잘못되는지? 저는 코드를 지옥의 불길 속으로 반복해서 던지고 다시 작성하려 했지만, 같은 좌절감을 다시 경험했습니다.
TypeScript에서는 이름 그대로 타입을 도입함으로써 이러한 두려움을 뒤로하고 있습니다. 변수와 함수에 그들이 전달하는 값, 기대값 또는 반환 타입을 주석으로 달고, 자바스크립트를 엄격한 타입 언어로 만듭니다. 작성하는 코드 한 줄마다 코드의 신뢰성과 일관성을 자동으로 테스트합니다. 기본 예시를 살펴보겠습니다.

게다가 컴파일러가 불일치를 발견하면 비명을 지르기 때문에 쉽게 추적할 수 있습니다. 그 멋진 서드파티 라이브러리를 사용하는 경우, TypeScript는 개발자들이 문서의 바다에 빠지지 않고 자신의 코드를 소통하고 정보를 전달할 수 있는 방법을 제공합니다.
이것이 TypeScript의 핵심 용도라고 생각합니다. 하지만 우리는 훨씬 더 강력한 무언가의 표면만 긁었을 뿐이라고 생각합니다. 흥미로운 사례들을 차근차근 설명해 드리겠습니다.
알 것인가 알 것인가 모르는 것, 알 수 없는 것들 vs 어떤 것도요
입력을 그대로 반환해야 하는 함수를 작성한다고 상상해 보세요. 'any' 타입을 사용해 이를 구현할 수 있습니다. 'any' 타입은 모든 것을 받아들입니다; 문자열과 숫자; 배열과 객체; 신용카드와 사과도요. 음, 후자는 아닐 수도 있지만, 어떤 유형의 변수든 받아들일 수 있습니다.

이 모든 것은 허용되는데, 변수가 'any' 타입을 가졌기 때문입니다.
하지만 마지막 줄에는 뭔가 수상한 점이 있습니다. 원래 '문자열' 타입으로 선언된 변수에 '숫자'를 부끄러움 없이 할당할 수 있습니다. 제가 여기서 증명하려는 것은 정확히 그렇지 않나요? 걱정 마세요, '미지' 타입이 구원에 나섭니다!

그리고 우리는 다시 본격적으로 돌아왔습니다! '미확인' 타입에는 무엇이든 할당할 수 있지만, '더 강한' 타입 변수에는 할당할 수 없습니다.
제네릭으로 치료됨
우리는 방금 'any'와 'unknown' 타입을 사용해 어떤 것도 받아들이는 함수를 만드는 방법을 보았습니다. 하지만 우리는 입력을 다른 유형의 값으로 무의식적으로 바꾼 것은 아님을 신뢰해야 합니다. 결국 함수는 'any' 타입을 반환할 것입니다.
이 불안정성을 해결하기 위해 제네릭 타입을 도입할 수 있습니다. 제네릭 타입은 함수에 전달된 타입을 반환할 수 있게 해줍니다.

함수를 호출할 때 'T' 타입을 제공함으로써 입력의 타입을 지정할 수 있습니다. 함수는 'T'와 같은 타입을 반환한다고 명시하므로, 어떤 결과가 나오는지 알 수 있습니다. 편안히 쉬면서 스쿠비 스낵을 즐기세요 - 아마도 기사를 읽은 후에 말이죠.
함수 표기법에 관해서는, 저는 화살표 표기법을 사용하지 않는다는 점을 주목하세요. 화살표 표기법을 사용하려면 JSX를 사용할 때 약간 혼동될 수 있습니다.

우리가 기대하는 표기법이 JSX를 사용할 때는 작동하지 않는다는 것을 알 수 있습니다. 그 이유는 컴파일러가 입력 타입 정의와 JSX 문법을 혼동하기 때문입니다. 이 문제는 쉼표를 추가하고 두 번째 타입을 생략함으로써 우회할 수 있습니다. 이 표기법은 JSX에 유효하지 않으며, 컴파일러가 우리 코드를 일반적인 타입 정의로 해석하게 만듭니다. 휴!
논박에 관한 논쟁, 절대 안 하는 타입
추억을 되새겨 보세요. 두 가지 값을 받아야 하지만 한 번에 한 종류만 받아야 하는 함수를 작성해본 적 있나요? 다음과 같은 내용을 쓴 기억이 있나요?
_"두 값이 모두 제공되면, 오류를 던지세요. 왜냐하면 한 값만 제공해야 하니까요." _

그리고 아마도 더 흔한 일일 것이다.
"이 인자가 제공된다면, 이것을 따르세요. 만약 제공되지 않았다면, 그걸로 가세요"

그리고 가장 중요한 규칙을 잊으면 안 되겠지.
_"값이 제공되지 않으면 오류를 던집니다." _

이것은 장황하고 매우 보기 흉한 행위입니다. 다행히도 TypeScript에는 이 요구사항을 더 자연스럽고 덜 침해적으로 충족시키는 방법이 있습니다. 절대 시도하지 말자!

함수가 두 타입 중 하나의 속성을 가진 객체를 받아들이길 원하지만, 두 타입 모두를 받아들이지 않기를 원합니다. 원하지 않는 인자를 '절대' 타입으로 선언하면, 컴파일러가 속성을 모두 전달하려 할 때 오류를 발생시킵니다.
_What 속성을 '절대' 타입으로 선언하는 것과 단순히 타입에서 제거하는 것의 차이가 무엇인가요?
원하지 않는 속성을 단순히 생략하면, 컴파일러는 두 인자를 모두 가진 함수 호출을 받아들일 것입니다. 이 경우 이 경우 처리 책임을 함수에 다시 넘깁니다. 마이크로매니지먼트가 가장 잘하는 일을 하세요; 책임을 넘기세요!
노조 유형, 중복 및 제외
여러 값을 허용하고 싶다면 '|'를 사용해 유니언 타입을 만들 수 있습니다.

충분히 쉬워서, 이제 좀 더 흥미로운 걸로 넘어가겠습니다.
타입을 결합하는 대신 '&'를 사용해 겹치는 타입만 허용할 수 있습니다. 이 방법은 일부 타입을 수용하지만 모두 수용하지 않는 두 다른 함수를 호출하는 함수를 작성할 때 유용한 연습이 될 수 있습니다. 두 함수 모두에서 받아들여지는 타입만 제공될 수 있음을 보장할 수 있습니다.

좋아요, 모든 값과 겹치는 타입을 성공적으로 선택했습니다! 하지만 고유 타입이 선택되는 경우가 하나 남아 있습니다. 'Exclude' 타입을 사용하면 첫 번째 인자에 있는 값과 두 번째 인자에 있는 값들을 제외할 수 있습니다.

우리는 절반 지점에 도달했습니다. 첫 번째 비겹 타입은 선택했지만, 두 번째 비중복 타입은 거부되었습니다. '|'와 '제외'의 거듭제곱을 합쳐 이를 고쳐봅시다.

이제 우리는 끝났어, "박수 박수" 우리에게!
이제 오브젝트와 함께 픽과 오밋을 소개합니다
객체 타입을 결합하는 것은 꽤 간단합니다. 이전 섹션에서는 겹치는 타입을 선택할 때 '&'를 사용했습니다. 하지만 오브젝트의 경우, '&'는 두 타입의 속성이 모두 필요한 타입이 됩니다.

타입을 빼는 것은 조금 더 복잡합니다. 'Omit' 타입을 사용해 객체에서 필요한 속성을 제거할 수 있습니다. 하지만 'Omit'의 두 번째 매개변수는 객체를 받아들이지 않고, 'Exlude' 타입처럼 문자열 리터럴 타입을 수락합니다. 'keyof'을 사용해 객체의 키를 얻을 수 있으며, 다음과 같은 해결책이 나옵니다.

만약 겹치는 속성만 유지하고 싶다면 'keyof'를 다시 사용할 수 있지만, 이번에는 'Pick' 타입을 사용할 수 있습니다.

기록과 함께 기록 유지해
저처럼 5분마다 주머니를 확인하며 잃어버린 게 있는지 확인하는 분이라면, TypeScript가 큰 도움이 됩니다. TypeScript를 사용하면 'Record' 타입으로 키를 선언하는 것을 잊지 않았는지 확인할 수 있습니다.
추가적인 정보를 가진 '빅4' 메탈 밴드 두 밴드를 선언해 보겠습니다. (죄송합니다, 메탈리카와 앤스랙스입니다.)

우리의 상수는 두 밴드 모두 선언되어야 통과할 수 있습니다.
파셜과 함께 긴장을 풀어
이제 'Record'를 제대로 돌려보세요. 모든 키가 필요 없다면? 이전에 정의한 타입을 사용하고, 이번에는 'Partial'과 함께 사용합니다.

이제 밴드의 부분집합을 정의할 수 있습니다.
_Are 너무 허둥대는 게 우리 발등을 찍는 거 아니지?
아니요! 이제는 모든 것을 암묵적으로 허용하는 대신 어느 정도의 관대함을 명시적으로 허용합니다. 그리고 안심하세요, 다른 유형의 모든 속성은 여전히 정의해야 합니다!
단호하게 해야 한다는 뜻이야
반면, '필수' 타입을 사용해 선택적 속성을 필수로 만들 수도 있습니다.

읽기와 함께 당신의 재산을 보호하세요
변수를 상수로 선언하여 값이 변경되지 않도록 할 수 있습니다. 하지만 객체를 상수로 선언할 때도 그 속성의 값을 변경할 수 있습니다. 'Readonly' 타입을 사용해 이를 방지할 수 있습니다.

우리는 단순히 '읽기 전용' 타입으로 타이핑을 하면 거의 다 끝납니다!
결론: 끈;
물론, 다른 다양한 사용 사례와 흥미로운 기능들도 많습니다. 하지만 이런 예시들을 통해 TypeScript는 우리에게 엄격함을 요구하면서도 충분한 유연성을 제공합니다. 어떤 타입을 다루든, 원하는 것을 얻을 수 있는 방법은 항상 있습니다. 동시에 이 기술은 우리의 코드를 신뢰성 있게 만들고 어떤 프로젝트든 성장할 준비를 합니다. TypeScript에 대한 확립된 지원과 이를 사용하는 수많은 프로젝트들 덕분에, TypeScript가 곧 사라지지 않을 것임을 말할 수 있습니다.
Typescript 글자의 힘을 즐기고 탐험해 보세요!