[TS] TypeScript 기초

박하늘·2025년 4월 8일

▪️ 타입스크립트(TypeScript)란?

마이크로소프트(Microsoft) 에서 개발한 자바스크립트의 상위 집합(Superset) 언어
즉, 자바스크립트에 “정적 타입(Static Type)“을 추가한 언어

  • .ts 확장자를 사용함
  • 자바스크립트로 변환(트랜스파일)해서 실행됨
  • 자바스크립트의 모든 기능을 포함하면서, 타입을 명시할 수 있는 문법을 제공해
  • TypeScript 는 Microsoft 에서 개발 및 유지 관리하는 오픈 소스 언어
  • 큰 스케일의 애플리케이션 개발을 위해 설계된 언어
  • JavaScript 에 정적 타이핑선택적 타입 annotation 추가



▪️ 타입스크립트 주요 특징

  • 크로스 플랫폼 : TypeScript는 JavaScript가 실행되는 모든 플랫폼에서 실행된다.
  • 객체 지향 언어 : TypeScript는 클래스, 인터페이스, 모듈과 같은 강력한 객체 지향 프로그래밍 기능을 제공한다
  • 정적 타입 검사 : TypeScript는 정적 타이핑을 사용하며, 이는 타입 annotation(타입 주석) 을 통해 수행된다.
    이를 통해 컴파일 시에 타입 검사가 가능하므로, 스크립트를 매번 실행하지 않고도 코드 작성 중에 오류를 찾기 쉽다
  • 타입 추론 : 변수가 타입 없이 선언되면, 그 값에 기반하여 타입을 추론하는 기능을 제공한다
  • 선택적 정적 타이핑 : TypeScript의 정적 타입은 선택적이다
  • DOM 조작 : JavaScript처럼 TypeScript도 DOM을 조작하는 데 사용할 수 있습니다.
  • ES 6 기능 포함 : TypeScript는 클래스, 인터페이스, 화살표 함수 등 예정된 ECMAScript 2015의 대부분 기능을 포함하고 있습니다.

[자바스크립트 + 타입 = 타입스크립트]

타입스크립트는 타입시스템 을 기반으로 한 언어

타입시스템

  • 타입 시스템은 데이터의 종류를 구분하는 분류 체계를 뜻한다.

  • 이 시스템은 데이터가 메모리에 어떻게 저장되고, 어떻게 처리되어야 하는지에 대한 규칙을 정의합니다.

  • 타입 시스템의 가장 큰 목적은 프로그램의 안정성과 신뢰성을높이는 것

    [핵심 개념 1] : 타입 안정성 (type safety)

    • 프로그램이 예상치 못한 방식으로 데이터를 해석하는 오류를 미리 방지 하는 것을 의미.
    • 예) 문자열과 숫자를 혼동하여 연산하는 것과 같은 실수를 막아준다.

    [핵심 개념 2] : 타입 추론 (type inference)

    • 명시적으로 타입을 지정하지 않아도, 컴파일러가 자동으로 데이터의 타입을 결정하는 프로세스.
    • 코드의 간결성 (가독성) 을 높이면서도 타입의 안전성을유지할 수 있게 해준다.

    [핵심 개념 3] : 정적 vs 동적 타입 (static vs dynamic)

    • 정적 타입(Static Typing): 컴파일 시에 타입이 결정되며, 런타임에는변경되지 않는다.
      (정적 타입 언어는 실행 전에 타입 오류를 잡을 수 있어 안정성이 높다)

    • 동적 타입(Dynamic Typing): 런타임에 타입이 결정됩니다. 동적 타입 언어는 더 유연하다
      (런타임에 타입 관련 오류가 발생할 수 있다)

    [핵심 개념 4] : 제네릭 (generics)

    • 타입 매개변수를 (예 <T>) 사용하여 다양한 타입에 대해 동작할 수 있는 코드를 작성할 수 있게 해준다.
    • 코드의 재사용성을 높이고 타입 안전성을 보장한다.

[기본적인 동작원리]

  1. 파싱 − 타입스크립트 컴파일러가 코드를 파싱하여 추상 구문 트리(AST) 모델을 생성

  2. 타입검사 - 컴파일러는 코드를 검토하여 변수, 함수 및 표현식의 타입을 결정한다. 또한, 이 과정을 통해 타입 오류를 찾는다

  3. 파일 생성 - 타입스크립트 코드가 타입 검사를 거친 후, 컴파일러는 자바스크립트 코드를 생성하며 생성된 자바스크립트 코드에서는 타입 주석(annotation)이 제거된다




▪️ JS vs TS

JavaScript 는 웹의 표준 언어로, 동적인 웹사이트와 애플리케이션을 만드는 데 필수적인 도구이다.
하지만 JavaScript만으로는 프로그램의 복잡성이 커질 때 발생할 수 있는 여러문제들을 해결하기 어렵다.

TypeScriptJavaScript의 상위 집합으로, JavaScript의모든 기능을 포함하면서도 정적 타입 검사와 같은 강력한 기능을 추가한다.

[ JS vs TS 표 ]

특징JavaScriptTypeScript
타입 시스템동적 타입. 변수의 타입은 런타임에 결정됨정적 타입. 변수의 타입은 컴파일 시점에 결정됨
타입 안정성타입 오류가 런타임에 발생할 수 있음 (낮은 타입 안정성)타입 오류는 대부분 컴파일 시점에 발견됨 (높은 타입 안정성)
컴파일인터프리터 언어로, 소스 코드가 런타임에 해석됨컴파일 언어로, TypeScript 코드는 JavaScript로 컴파일되어 실행
학습 곡선비교적 쉬움JavaScript에 비해 다소 어려움. 타입 시스템과 추가 문법을 학습해야 한다
인터페이스와 제네릭지원하지 않음지원함
호환성모든 브라우저와 환경에서 기본적으로 지원됨.JavaScript로 컴파일되어야 브라우저와 환경에서 실행될 수 있음.
개발도구 지원기본적인 자동완성, 덜 강력한 추론더 강력한 자동완성, 코드 분석
프로젝트 규모소규모에 적합대규모 프로젝트에 특히 유리

[예시 코드 비교]

📍 [JS]

// 📍 1. 다른 자료형에 대한 오류가 바로 확인되지 않음 (문제가 없는 코드로 인식)
let num = 5;
num = "five";

// 📍 2. null , undefined 와 같은 자료형 출력 시 런타임에 오류 발견됨
let a = null;
console.log(a.name);

// 📍 3. heigt 이렇게 프로퍼티 오류가 나면 컴파일 시에는 확인이 불가하며 런타임 시 확인 가능
let obj = {
    width: 320,
    height: 640
};

let area = obj.width * obj.heigt;

// 📍 4. 파라미터 값을 하나만 주었을 경우 런타임 시 오류
function add(a,b){
    return a + b
};

add(1);

// 📍 5. 이 코드는 자바스크립트에서 "undefined" 를 반환한다.
function getName() {
}

const myName = getName();

// 📍 6. 반환값 미지정 시 
function getDouble (value) {
    if(value < 10) {
        return value * 2
    }
}

getDouble(9) // 18 반환
getDouble(15) // undefined

// 📍 7. == 두개인 경우 동등연산자 / === 일치 연산자
// 동등 연산자의 경우 자바스크립트에서는 타입을 자동으로 바꿔서 적용시켜준다
// 즉 아래와 같은 예제는 true 로 반환이 된다
if("0" == 0){
    //true
}
// 📍 8. 타입이 다른 값을 push 해도 정상 적용된다
let fruits = ["apple", "banana", "orange"]
fruits. push (5)

// 📍 9. p 에 대해서는 따로 구조분해 할당을 해주지 않았지만 런타임 시 undefined 로 확인이 된다
const arr = [1,2,3];
const [x,y,z,p] = arr; // p: undefined

📍 [TS]

// 📍 1. 다른 자료형에 대한 오류 바로 확인 가능
let num = 5;
num = "five";

// 📍 2. a 라는 객체가 null 일 수 있기 때문에 a 위에 마우스를 올리면 오류가 발생한다
let a = null;
console.log(a.name);

// 📍 3. heigt 이렇게 프로퍼티 오류가 나면 바로 잘못된 프로퍼티라고 알려주면서, 올바른 프로퍼티 명도 제안해준다.
// Property 'heigt' does not exist on type '{ width: number; height: number; }'. 
// Did you mean 'height'?
let obj = {
    width: 320,
    height: 640
};

let area = obj.width * obj.heigt;


// 📍 4. 파라미터 값을 하나만 주었을 경우 b 파라미터는 any 라는 값을 가진다
// any type 은 타입 스크립트에서 권장하지 않음
// An argument for 'b' was not provided. (b 파라미터 값이 선언되지 않았다고 알려줌)
function add(a,b){
    return a + b
};

add(1);

// 📍 5. 반환값에 대한 자료형을 지정해주면 해당 자료형을 반환해야 한다는 오류가 뜬다
// A function whose declared type is neither 
// 'undefined', 'void' nor 'any' must return a value. ts (2355)
function getName1(): string {
}

const myName1 = getName1();

// 5-1. 이렇게 빈 문자열이라도 리턴해주면 오류가 사라진다
function getName2(): string {
    return ""
}

const myName2 = getName2();


// 📍 6. 반환값 미지정 시 
// value에 대한 타입 = number , return 값에 대한 타입도 number 로 지정
// Function lacks ending return statement 
// and return type does not include 'undefined'.ts(2366)
// 10 이상일 경우 적절한 반환값이 없다는 오류
function getDouble (value: number): number {
    if(value < 10) {
        return value * 2
    }
}

getDouble(9) // 18 반환
getDouble(15) // undefined

// 📍 6-1. 이렇게 모든 경우에 대한 반환값을 줘야 한다
function getDouble1 (value: number): number {
    if(value < 10) {
        return value * 2
    }
    return 0;
}

getDouble(9) // 18 반환
getDouble(15) // undefined

// 📍 7. 여기서 동등 연산자는 타입이 같아야 한다.
// 로직 자체를 실행할 수 없음 잠재적인 버그를 막아준다
if("0" == 0){
    
}

// 📍 8. 타입이 다른 값을 push 하면
// Argument of type 'number' 
// is not assignable to parameter of type 'string'.
// 과 같은 오류 발생
let fruits = ["apple", "banana", "orange"]
fruits. push (5)

// 📍 9. p 에 대해서는 따로 구조분해 할당을 해주지 않으면 ....
// Tuple type '[number, number, number]' 
// of length '3' has no element at index '3'.
// 과 같이 index 3번에는 접근할 수 없다는 오류가 뜬다
const arr1: [number, number, number] = [1,2,3];
const [x,y,z,p] = arr1; // p: undefined



▪️ 설치하기

  • Node.js
    https://nodejs.org/

  • Node.js + NPM (node package manager)

  • 코드 에디터 설치 (Visual Studio Code)
    https://code.visualstudio.com/

  • TypeScript 설치
    https://www.typescriptlang.org/

    // 💡 [설치]
    // 해당 프로젝트에 설치 (개별적)
    npm install typescript --save-dev
    
    // 코드에디터 전역에 설치
    npm install -g typescript
    
    // 💡 [초기화]
    // 타입스크립트 설정파일 설치 - tsconfig.json 파일 생성
    tsc --init



사용하기

index.ts 라는 파일은 실행시킬 때 ..

  1. tsc index.ts
    → 타입스크립트를 자바스크립트로 컴파일
  2. ls -la
    → 자바스크립트 파일이 생성되었는지 확인
  3. node index.js
    → Node.js로 컴파일된 파일 실행

[tsconfig.json 파일 안의 "compilerOptions" 설정]

tsc --init 를 사용하여 타입스크립트 초기화를 해주면 자동으로 tsconfig.json 파일에 아래와 같이 기본적인 설정이 세팅된다.

{
  "compilerOptions": {
    // 컴파일된 자바스크립트가 어떤 버전의 JS 문법으로 변환될지 지정
    "target": "es2016",
    // 모듈 시스템 형식을 지정
    "module": "commonjs",
    // import 를 더 쉽게 할 수 있도록 / true로 하면, CommonJS 모듈도 ES 스타일로 쓸 수 있어서 편함
    "esModuleInterop": true,
    // 대소문자 구분이 파일 이름에서도 일관되게 사용되도록 강제
    "forceConsistentCasingInFileNames": true,
    // 타입스크립트의 모든 엄격한 타입 검사 기능을 활성화
    "strict": true,
    // node_modules에 있는 타입 정의 파일(.d.ts)들은 검사하지 않음
    "skipLibCheck": true
  }
}

[1] 기본 설정대로 컴파일 시 ...

  • 맨 상위 파일에 파일명이 같은 js 파일이 자동 생성

[2] outDir 설정 추가 시 ...

// 컴파일된 .js 파일이 저장될 디렉토리 설정
"outDir": "dist"

  • outDir 로 지정해준dist 라는 폴더 안에 파일명이 같은 js 파일이 자동 생성

[3] include 설정 추가 시 ...

// src/ 폴더 안에 있는 모든 폴더, 모든 파일을 포함하겠다는 뜻
"include": ["src/**/*"]
src/
├── index.ts
├── utils/
│   └── helper.ts
└── components/
    └── Button.ts
  • 위 구조에서는 index.ts, helper.ts, Button.ts 전부 컴파일 대상이 됨

[4] noUncheckedIndexedAccess 설정

"noUncheckedIndexedAccess": true
  • 객체나 배열에 인덱스를 통하여 접근 시 더 엄격한 타입검사를 수행



▪️ 타입 주석

  • 타입스크립트 문법으로, 변수, 함수, 객체 등에 명시적으로 타입을 지정하는 방법을 말한다
  • 컴파일러는 이 정보를 바탕으로 타입 검사를 수행한다
  • 타입스크립트의 기본 타입에는 string, number, boolean, null, any 등이 있다

[예제]

// [ 기본 타입 ]
                  
// 📍 [ 문자열 (string) ]
const a: string = "";
const b: string = "";
const c: string = ``; // 템플릿 리터럴

let myName: string = "Steve";
let message: string = `Hello, ${myName}`;

// myName. 후에 string 관련 메소드들이 뜬다 오타가 나지 않게 잘 사용하기
myName. toLocaleUpperCase()

// 이전에 이미 string 으로 타입 지정을 해주었기 때문에 숫자로 재지정하지 못함
message = 123

// 📍 [ 숫자 타입 (number) ]
let n: number = 100;

// 숫자 타입만 지정 가능 오류
n = "100"

// 문자 타입 메소드 사용 불가 오류
n. toUpperCase() ;

// 아래처럼 모든 숫자들은 number 로 지정 가능
let count: number = 10;
let price: number = 9.99;
let temperature: number = -15;
let distance: number = 3.4e-5;

let total: number = count * price;
let average: number = total / 2;

let infinity: number = Infinity;
let minusInfinity: number = -Infinity;
let iAmNotANumber: number = NaN;

// 📍 [ 불리언 (booLean) ]
let isOpen: boolean = true;
let isCompleted: boolean = false;

if(isOpen) {
    console.log ("hello we are open!")
}
if(!isCompleted) {
    console. log("job not complete")
}

// 📍 [ && || ! 사용하기 ]

let isAvailable: boolean = isOpen && !isCompleted;

// 📍 [ null ] - 의도적으로 값이 없음을 명시할 때 사용
// 유니언 타입(두 개 이상의 타입을 가질 때)과 함께 종종 사용된다
let user: string | null = null;

function login(userName: string) {
    user = userName;
}
function logout() {
    user = null;
}

login ("Joey")
logout ()

// null 은 값이 없음 , undefined 는 값이 할당되지 않음

// 📍 [ any 타입 ] -  모든 타입을 허용함 , 타입 체크를 하지 않음 (사용을 권장하지 않음)
// 타입 서비스의 이점을 포기하고 유연성을 가져가겠다
let someValue: any;
someValue.toString;
someValue = false;
someValue.toFixed();

0개의 댓글