Front-end/TypeScript

TypeScript 기본

kwon-jin2-development 2024. 10. 15. 14:28

TypeScript는 JavaScript에 타입을 추가한 언어이다. 기본적으로 JavaScript의 모든 기능을 포함하면서, 컴파일 시 코드의 오류를 미리 잡을 수 있도록 도와준다. 

 

1. 타입

TS 핵심 기능 중 하나는 변수가 가질 수 있는 값의 타입을 명시적으로 지정할 수 있다는 것이다. 자바스크립트에서는 변수가 어떤 타입의 값을 가질지 명확히 정해져 있지 않지만, 타입스크립트에서는 타입을 정의함으로써 코드의 안정성과 예측 가능성을 높일 수 있다.

// string
let name: string = 'Lois';

// number
let age: number = 25;

// boolean
let isStudent: boolean = true;

// array
let numbers: number[] = [1, 2, 3];
let strings: string[] = ['hello', 'world'];

// any
let anything: any = 'I can be anything!';
anything = 42;

JS 말고 TS를 사용하는 이유는 JS도 typeof를 통해 타입을 검사하고 조건문으로 오류를 던져서 잡을 수 있지만, 기본적으로 JS는 런타임 시 오류를 확인할 수 있지만, TS는 컴파일 시 오류를 미리 잡을 수 있도록 도와준다. 

let price: number = 100;
price = 'Free';  // 에러 발생: 'string'은 'number' 타입에 할당할 수 없음

2. 타입 추론

TS에서는 모든 변수에 타입을 명시적으로 지정할 필요는 없다. 타입스크립트는 변수가 할당된 값을 보고 자동으로 타입을 추론한다. 이를 타입 추론이라고 한다.

let greeting = 'Hello, TypeScript!';
greeting = 123;  // 에러 발생: 'number' 타입은 'string' 타입에 할당할 수 없음

위 코드에서 greeting 변수에 "Hello, TypeScript!"라는 문자열이 할당되었다. TS는 이 값을 보고 greeting의 타입을 **string**으로 자동으로 추론한다. 따라서 오류를 발생시킨다:

타입 추론의 장점으로는

  • 간결함: 코드가 간결해지면서도 타입 안정성을 유지할 수 있다.
  • 명확성: 타입을 일일이 지정하지 않아도 타입스크립트가 추론을 통해 오류를 방지힌다.
  • 유연성: 명시적으로 타입을 지정하지 않아도 타입스크립트는 문맥을 보고 자동으로 타입을 결정하므로 유연하다.

하지만 타입스크립트가 추론할 수 없는 복잡한 경우나 any와 같이 너무 유연한 타입이 사용될 때는 명시적인 타입 선언이 더 안전할 수 있다. 예를 들어 함수의 반환 타입을 명확히 지정해주는 것이 좋다.

function getSum(a: number, b: number) {
  return a + b;  // 자동으로 반환 타입은 'number'로 추론됨
}

 

3. 객체 타입

객체를 생성할 때, 객체의 속성 각각에 타입을 지정할 수 있다.

let person: { name: string; age: number } = {
  name: 'Lois',
  age: 25
};

person.name = 123;  // 에러: 'number' 타입은 'string' 타입에 할당할 수 없음

 

이 예시에서 person 객체는 name 속성은 문자열(string), age 속성은 숫자(number) 타입으로 정의된다.객체의 각 속성에 맞는 타입을 지정하면, 타입스크립트는 해당 타입에 맞지 않는 값을 할당할 때 에러를 발생시킨다.

4. 튜플 타입

튜플(Tuple)은 TypeScript에서 고정된 개수의 요소를 가지며, 각 요소의 타입이 미리 정의된 배열을 말한다. 즉, 배열과 비슷하지만, 배열의 각 위치에 특정 타입을 지정할 수 있는 것이 튜플의 특징이다. 배열은 모든 요소가 같은 타입일 때 사용하지만, 튜플은 각 요소가 서로 다른 타입일 수 있다.

let person: [string, number];
person = ['Lois', 25];  // 첫 번째 요소는 문자열, 두 번째 요소는 숫자

person = [25, 'Lois'];  // 에러: 순서가 잘못됨

이 예시에서는 person이라는 튜플이 있고, 첫 번째 요소는 string 타입이어야 하며, 두 번째 요소는 number 타입이어야 한다. 만약 다른 타입이나 순서로 값을 할당하려고 하면 에러가 발생한다.

튜플의 특징으로는 

 

  • 고정된 길이: 튜플은 정의된 타입의 순서와 길이를 정확히 따라야 한다. 길이가 다르거나 타입 순서가 잘못되면 에러가 발생한다.
  • 요소별 타입 지정: 배열과 달리, 튜플은 각 위치에 특정 타입을 지정할 수 있다. 예를 들어, 2개의 값을 가진 튜플을 만들고, 첫 번째 값은 문자열, 두 번째 값은 숫자일 수 있다.

또한 튜플에서도 선택적인 요소를 만들 수 있다. 선택적 요소는 튜플의 마지막에만 위치할 수 있습니다. 선택적인 속성에는 ?를 사용한다.

let userInfo: [string, number?, boolean?];
userInfo = ['Alice'];  // 선택적 요소는 없어도 됨
userInfo = ['Alice', 30];  // 두 번째 요소까지 채울 수도 있음
userInfo = ['Alice', 30, true];  // 모든 요소를 채울 수도 있음

 

 

 

튜플도 배열처럼 다양한 메서드를 사용할 수 있지만, 주의할 점은 튜플의 타입 안전성이 메서드에 의해 깨질 수 있다는 것이다. 예를 들어, push 메서드를 사용하면 튜플의 길이가 고정되지 않고 새로운 값을 추가할 수 있기 때문에, 원래 정의된 타입과 일치하지 않는 값이 들어갈 수 있다.

let user: [string, number] = ["Lois", 25];
user.push(100);  // 타입 에러는 발생하지 않지만, 의도된 튜플의 타입 안전성을 해침.
console.log(user);  // ["Lois", 25, 100]

튜플은 구조 분해 할당(destructuring)을 통해 각 요소를 쉽게 변수에 할당할 수 있다.

let rgb: [number, number, number] = [255, 100, 50];
let [red, green, blue] = rgb;

console.log(red);   // 255
console.log(green); // 100
console.log(blue);  // 50

튜플은 함수의 반환 값이 여러 개일 때 유용하게 사용할 수 있다. 예를 들어, 함수가 좌표를 반환할 때 튜플을 사용하여 x, y 값을 반환할 수 있다.

function getCoordinates(): [number, number] {
  return [10, 20];
}

let [x, y] = getCoordinates();
console.log(x);  // 10
console.log(y);  // 20

5. enum (열거형)

enum은 TS에서 값들의 집합에 이름을 부여하여 목록 형태로 사용할 수 있게 하는 타입이다. 여러 값들을 하나의 그룹으로 묶어서 사용할 때 유용하다.

enum Day {
  Sunday,    // 0
  Monday,    // 1
  Tuesday,   // 2
  Wednesday, // 3
  Thursday,  // 4
  Friday,    // 5
  Saturday   // 6
}

let today: Day = Day.Monday;
console.log(today);  // 1

enum은 대문자로 시작하며 기본적으로 0부터 시작하는 숫자 값을 자동으로 할당한다. Day.Monday로 요일을 참조하면 1이라는 숫자로 해석된다. 수동으로 값을 할당하는 것 또한 가능하다.

enum Day {
  Sunday = 7,
  Monday = 1,
  Tuesday = 2,
  Wednesday = 3,
  Thursday = 4,
  Friday = 5,
  Saturday = 6
}

console.log(Day.Sunday);   // 7
console.log(Day.Monday);   // 1
enum Direction {
  Up = 'UP',
  Down = 'DOWN',
  Left = 'LEFT',
  Right = 'RIGHT'
}

let move: Direction = Direction.Up;
console.log(move);  // 'UP'

숫자 enum의 경우 역방향 매핑이 가능하다. 즉, 숫자 값을 사용해 열거형 이름을 찾을 수 있다.

enum Color {
	Red = 1,
    Green =,
    Blue
}

console.log(Color.Green) // 2
console.log(Color[2]) // Green

즉, 숫자 enum은 값을 통해 이름을 다시 참조할 수 있지만, 문자열 enum에서는 역방향 매핑이 지원되지 않음.

enum은 여러 상태나 옵션을 정의할 때 유용하게 사용할 수 있다. 예를 들어, 사용자 권한을 나타내는 enum을 정의할 수 있다.

enum UserRole {
	Admin,
    User,
    Cuest
}

function checkAccess(role: UserRole) {
	if (role === UserRole.Admin) {
    	console.log('관리자 접근 허용');
    } else if (role === UserRole.User) {
    	console.log('일반 사용자 접근 허용');
    } else {
    	console.log('손님 접근 허용')
    }
}

checkAccess(UserRole.Admin);  // 관리자 접근 허용
checkAccess(UserRole.Guest);  // 손님 접근 허용

이렇게 enum을 사용하면 숫자나 문자열로만 처리하는 것보다 의미가 명확하고, 코드의 가독성과 유지보수성이 높아진다.

 

const enum은 성능 최적화를 위해 사용된다. const enum은 컴파일 시점에 값으로 직접 변환되며, JS코드에서 실제로 enum을 참조하지 않음.

const enum Status {
  Success = 1,
  Failure = 0
}

let status: Status = Status.Success;
console.log(status);  // 1

 

'Front-end > TypeScript' 카테고리의 다른 글

TypeScript 기본 (3)  (0) 2024.10.21
TypeScript 기본(2)  (0) 2024.10.15