본문 바로가기
개발공부일지/TypeScript

TypeScript - 타입스크립트 기초 알아보기

by Hynn1429 2023. 4. 18.
반응형

안녕하세요.

Hynn 입니다.

 

이번 포스팅에서는 JavaScript 의 상위 집합(superset) 이라고 불리기도 하고, 현업에서도 상당히 많이 사용되는 TypeScript 에 대해서 알아보도록 하겠습니다.

JavaScript 의 특성과 한계적인 부분을 극복하기 위한 대체언어로 많이 사용되고, 이를 실제 작성해보는 과정을 가져보도록 하겠습니다.

 

 

===========

===========

TypeScript, 즉 타입스크립트는 JavaScript 가 구조적으로 가지고 있는 문제점을 보완하는 역활을 하는 언어입니다.

즉, JavaScript 를 사용하여 개발하는 개발자들이 겪는 몇가지 문제점들을 구조적으로 개선하고, 보완하는 역활을 합니다.

따라서 작은 규모의 프로젝트나, 간단한 웹 페이지를 개발할 때 사용하지는 않지만, 현업에서 JavaScript 를 사용한다면, TypeScript 가 세트로 사용되는게 일상시되고 있습니다.

 

왜 그런것인지를 알아보려면 먼저, JavaScript 와 TypeScript 의 차이를 알아야 합니다.

 

1) 정적언어와 동적언어의 차이

 

먼저, JavaScript 는 동적언어(Dynamic Language) 입니다. 그리고 TypeScript 는 정적 언어(Static Language) 입니다.

이 두 언어의 가장 큰 차이는, 우리가 프로그래밍을 배우면서 가장 많이 듣고, 사용하는 "변수"의 타입 할당 방식에 따라 결정되는 타입입니다. 일반적으로 JavaScript 를 사용하여 코드를 작성하면, 동적언어이기 때문에, 코드를 작성하는 과정에서는 문법의 오류, 변수의 중복할당과 같은 문법에 의해 발생되는 오류는 코드 작성단계에서 파악이 가능하지만, 실제 함수가 동작하지 않거나, 의도한 동작이 이루어지지 않는 경우는 일반적으로 코드를 실행 할 때 결정됩니다. 즉 실행을 해 보아야 오류를 파악할 수 있습니다.

 

 반면에 TypeScript 는 정적언어로써, 코드를 실행하기 전에 Compile 시점에 변수의 타입이 결정됩니다. 그렇다 보니, 개발자는 변수를 선언할 때 변수의 타입을 "명시"해야 합니다. 변수의 타입을 명시하면, 해당 코드가 실행되는동안은 변경되지 않습니다. 이렇게 함으로써 얻는 가장 큰 장점을, 컴파일 시점에 타입에 관련된 오류를 잡아낼 수 있는것에 있습니다. 이를 예시를 통해 확인해보도록 하겠습니다.

 

const sum = (a, b) => a + b;
console.log(sum(1, "23"));

위 코드를 본다면, sum 이라는 변수명으로 선언한 이 함수는 일반적으로 값을 더하기 위해 만든 함수라고 유추할 수 있습니다.

하지만 JavaScript 에서 이 함수의 매개변수에 1, "23" 이라는 각각의 number, String 을 삽입하면, 형변환을 하는 것이 아니라, 코드 작성자의 작성 그대로, 1이라는 숫자와, 23이라는 문자열을 "연결" 하게 됩니다. 이렇게 작성이 될 경우, 의도한 결과를 얻었다고 보기는 어려울 겁니다. 물론 String + string 을 하여 문자를 연결하도록 의도할 수도 있지만, 일반적으로 이러한 작성을 하지는 않습니다.

 

반면에 TypeScript 에서 이를 적용하면, 조금 다른 결과를 출력할 수도 있습니다.

 

TypeScript 는 이러한 동일작성을 수행하면, 실행 전에도 이미 경고를 출력합니다.

위에서는 현재 매개변수에 대한 명시적인 타입을 부여하지 않았기 때문에, Editor 에서 "any" 라는 타입을 부여해서 경고를 출력했지만, 타입스크립트에서 any 를 사용할 것이라면, typescript 를 쓰는 이유가 없음을 이후의 과정에서 알게 될 겁니다.

 

위와 같은 형태에선 Typescript 는 일반적으로 각 매개변수의 타입을 명시해야 합니다.

이제 일반적인 의도대로, 타입을 명시하여 작성하면 오류가 새롭게 발생합니다.

 

const sum = (a: number, b: number) => a + b;
console.log(sum(1, "23"));

위의 형식을 보면, a 와 b 는 각각 number 라는 타입을 명시했습니다.

그렇다면 console.log 의 매개변수로 부여한 1, "23" 의 대한 오류를 반환하게 됩니다. 1의 경우 number 로 명시한 숫자의 타입을 만족하지만, "23" 은 String 으로, 숫자로 형변환을 하는것이 아니라, 명시된 타입에 맞지 않기 때문에 오류를 반환합니다. 

사소하다면 사소하다고 할 수 있겠지만, JavaScript에서 이러한 특성을 고려하지 않고, 있는 그대로 출력하기 때문에, 실제 실행 이후 결과물에서 오류를 확인하거나, 타입의 문제로 값이 "NaN" 과 같은 값으로 출력되는 오류를 한번쯤은 경험했을 것입니다. 

TypeScript 는 이러한 오류를 컴파일 단계에서부터 오류를 검사하고 엄격한 검사를 통해, 코드 작성과정에서도 문제점들을 꼼꼼하게 파악합니다.

 

2) JavaScript 의 모든 기능을 지원

 

TypeScript 를 위에서 간략하게 설명드린 바와 같이 이 언어는 JavaScript 의 상위라고 불리우는 이유는 당연하게도 TypeScript 는 최신 JavaScript 의 문법을 모두 지원할 뿐 아니라, TypeScript 에서 추가적인 몇가지 기능을 제공하고 있습니다. 이를 간단하게 알아보도록 하겠습니다.

 

  1. Type 검사
  2. Class & Interface
  3. Decorator 
  4. Enhancemenet Suppoirt IDE

위에서 언급한 엄격한 오류검사를 통해, Type 을 검사할 뿐 아니라, JavaScript 에서 사용했던 Class 문법을 JavaScript 보다 한층 더 객체지향 프로그래밍을 지원하고, Class 외에도 Interface 를 사용해서 코드를 보다 더 견고하게 구조화하고, 재사용성을 높일 수 있도록 지원합니다. 

 

 뿐만 아니라, JavaScript 는 ES 문법과, CommonJS 라는 두개의 유형의 문법이 존재하는데, 이 두가지를 모두 지원합니다. 즉 JavaScript 가 지원하는 문법이라면, TypeScript 역시 당연하게도 지원을 합니다. 

 

  마지막으로 IDE(Integrated Developmenet Environment), 통합 개발환경에서 개발자에게 개발 과정을 직접적으로 많은 도움을 줍니다. 이로 인해 개발과정의 속도를 높여주기도 하고, 코드의 품질이나 사용할 수 있는 환경을 빠르게 파악하는데 도움이 됩니다. 이는 몇가지 타입으로 구분되고, 별도의 라이브러리 및 확장 프로그램형태로 지원되는 부분도 있기 때문에, 필요한 부분을 찾아보시기를 권장드립니다.

 

  1. 타입 검사기(Type-Checker) : TypeScript 컴파일러는 타입 검사를 자동으로 수행하고, 타입 불일치, 인수 누락등의 오류를 발견하고 수정할 수 있도록 돕습니다.
  2. 코드 자동완성(Auto-completion) : 사용자가 TypeScript 의 작성을 시작하면, 현재 사용할 수 있는 코드 자동 완성 기능을 제공합니다. IDE가 코드 작성을 시작하면, 각 코드를 분석/추적하여 사용가능한 method, 변수 및 속성등을 제안함으로써, 코드 작성의 효율을 올려줍니다.
  3. 타입 정보 문서화 : Typescript 의 타입 정보를 활용하여, 변수,함수 및 클래스등의 타입의 정보를 표시해줍니다. 이를 활용하면 오류를 방지하고, 코드를 빠르게 이해하는데 도움이 됩니다.
  4. 디버깅 지원 : Typescript 를 지원하는 IDE 는 디버깅 도구를 제공합니다. 이 도구를 통해 브레이크 포인트를 설정하거나, 변수 값을 확인하고, 코드를 단계별로 실행할 수 있습니다.
  5. 리팩토링 : 디버깅 도구와 마찬가지로 IDE 에서 제공하는 도구를 사용하여 변수명 변경, 함수 추출 및 클래스 분할 등의 작업을 처리할 수 있습니다.
  6. 코드 탐색 : TypeScript 에서 제공하는 코드 구조 및 타입정보를 활용하여 클래스, 함수, 변수의 정의가 위치한 곳으로 쉽게 이동을 할 수 있습니다.
  7. 빌드 및 트랜스파일 : TypeScript 는 런타임이 포함되어 있지 않은 언어로, 브라우저에서 직접 실행할 수 없기 때문에, Babel 과 같은 트랜스파일러나, 별도의 컴파일러를 사용하여 TypeScript 코드를 JavaScript 로 변환해야 합니다. 이 작업을 손쉽게 수행할 수 있도록 돕습니다. 

IDE 는 우리가 잘 알고 있는 VisualStudio Code 와 같은 개발통합환경 Software 라고 이해하면 보다 쉽게 이해가 가능합니다.

 

TypeScript 를 학습하기 전에 앞서, TypeScript 의 핵심 개념을 알고 있어야 보다 효율적인 학습이 될 거라고 생각합니다.

아래의 핵심 개념을 이해한다면, TypeScript 학습에 많은 도움이 될 것이라고 생각합니다.

이를 간단한 표 형태로 정리해보도록 하겠습니다.

 

개념 설명
정적 타입(Static Type) TypeScript 는 JavaScript 와 같은 동적 타입이 아니라, 정적 타입의 언어입니다.
이러한 정적 타입의 언어는 변수, 함수, 매개변수 반환 값 등에 타입을 지정하고, 이를 통해 코드의 안정성을 높이고, 이로 인한 오류를 최소화하도록 지원합니다.
인터페이스 (Interface) 인터페이스는 TypeScript 에서 객체의 구조를 정의하는데 사용되는 추상화 개념의 핵심입니다. 
즉, 인터페이스를 사용하여 객체의 구조를 정의함으로서, 특정 객체가 필요로 하는 속성과 메서드를 명시적으로 지정하고, 코드의 가독성, 안정성을 높이게 됩니다.
클래스 및 상속 (Class & Inheritance) TypeScript 는 JavaScript 에서 사용되던 Class 를 보다 견고한 객체 지향 프로그래밍을 지원합니다. 
클래스를 사용하여 객체의 특성, 동작을 정의할 뿐 아니라, 상속을 통해 코드의 재사용성을 높입니다.
제네릭 (Generic) 제네릭은 타입 자체를 매개변수로 사용할 수 있게 해주는 기능입니다.
이를 통해 한번 작성된 코드를 다양한 타입에 작동하도록 작성할 수 있어, 코드의 재사용성을 향상시키고, 타입의 안정성을 유지할 수 있습니다.
접근 제어자(Access Modifiers) TypeScript 에서 클래스 속성 및 메서드에 대한 접근 제어를 위해 public, private, protected 와 같은 접근 제어자를 사용할 수 있습니다. 이를 사용하면 클래스의 캡슐화를 구현하고, 안정성을 향상시킵니다.
데코레이터 (Decorator) 데코레이터는 클래스, 메서드, 속성 및 매개변수 등에 추가기능을 부여할 때 사용합니다. 이를 사용하면 기존의 객체를 수정하지 않고도, 객체의 동작을 변경하거나 확장할 수 있습니다.
네임스페이스 및 모듈
(Namespace & Module)
네임스페이스와 모듈을 사용하면, 코드를 보다 구조화하고, 캡슐화를 향상시킵니다. 이를 통해 코드의 가독성과 유지보수성 측면을 향상시킵니다.
타입 추론
(Type Interface)
TypeScript 에서는 코드를 분석하여 자동으로 타입을 추론하는 기능을 제공합니다. 
만약 작성자가 타입을 명시적으로 지정하지 않았을 경우, 컴파일러는 가능한 경우, 적절한 타입을 추론하여 타입 오류를 방지하는데 도움을 줍니다.
유니언 타입 & 인터섹션 타입
(Union Type & Intersection Type)
때때로 반환되는 타입이 명시된 타입 한가지로 만족되지 않는 상황이 발생할 수 있습니다. 이를 TypeScript 에서 유니언 타입을 지원함으로써, 명시한 타입 중 하나임을 나타내는 유니언 타입과, 여러 타입의 조합을 허용한느 인터섹션 타입을 지원 합니다. 이를 통해 타입을 명시하더라도, 작성자가 의도한 바라면, 그를 올바르게 처리하는 데 도움을 줍니다.
타입 가드
(Type Guard)
타입 가드는 특정 코드 블록 내에서 변수의 타입 범위를 줄여서 사용할 수 있습니다. 이를 통해 타입 관련 오류를 방지하는데 도움이 됩니다.
타입 별칭
(Type Alias)
타입 별칭은 기존에 지정한 타입에 새로운 이름을 부여함으로서, 타입별로 매번 지정하게 되어 복잡해지는 것을 방지하고, 간결하게 표현할 수 있게 돕습니다. 이를 통해 코드의 가독성을 높일 수 있습니다.
맵드 타입
(Mapped Type)
기존 타입에 기반하여, 새로운 타입을 만드는 기능을 제공합니다. 
맵드 타입을 사용하면, 객체 타입의 모든 속성에 대한 작업을 수행하거나, 조건에 따라 속성을 선택적으로 포함하는 작업을 수행할 수 있습니다. 맵드 타입을 사용할 때는 "in" 키워드와 제네릭을 사용하여 정의합니다. 

 

다음 포스팅에서는 TypeScript 를 작성하기 전, Build & Complie 의 과정과 개념을 알아보도록 하겠습니다.

 

감사합니다.

반응형

댓글