타입스크립트 배열 / 객체 / 함수 타입

2025. 6. 4. 18:38Coding Study/Typescript

1. 배열 타입

배열은 자바스크립트에서 객체와 더불어 가장 자주 사용되는 자료구조 중 하나이다.
TypeScript에서 배열을 타입 지정한다는 것은 배열의 모든 요소가 동일한 타입을 갖도록 명시하는 것을 의미한다.
이를 통해 배열 내부 요소의 타입 안정성(type safety) 을 확보할 수 있다.

 

 

  1)  배열 타입 선언 방법

TypeScript에서는 배열 타입을 표현하는 방법이 두 가지가 있다.

  • 타입[] 형태로 선언
  • Generic 형태로 선언 (Array<타입>)

둘 다 동일한 기능을 제공하지만, 1번 방법이 더 대중적이며 현업에서도 자주 사용된다.


 

 2)  배열 타입 선언

  📎 예제 코드

// 방법 1: 타입[] 형태
let nums: number[] = [1, 2, 3];
let strs: string[] = ['a', 'b', 'c'];

// 방법 2: Generic 형태
let nums2: Array<number> = [4, 5, 6];
let strs2: Array<string> = ['d', 'e', 'f']

 

위 예제에서 nums와 nums2는 모두 숫자 배열이며, strs와 strs2는 문자열 배열이다.
표현 방법만 다를 뿐 실제 동작은 동일하다.


⚠️ 타입 오류 예시

let bools: boolean[] = [false, true, false];

bools.push(true);   // OK
bools.push("true"); // ❌ 오류

 

타입스크립트는 정적 타입 검사(static type checking) 를 통해 잘못된 타입이 배열에 들어가는 것을 막아준다.


📘 boolean 배열 예제

let bools: boolean[] = [false, true, false];

bools.push(true);   // OK
bools.push("true"); // ❌ 오류

 

배열 요소의 타입이 명확하게 지정되어 있기 때문에, 다른 타입을 추가하려고 할 경우 즉시 에러를 발생시켜준다.


3)  인텔리센스(자동완성) 예시

배열 타입이 명시되어 있으면 에디터 자동완성 기능(인텔리센스) 을 사용할 수 있어 개발 생산성이 높아진다.

 

let fruits: string[] = ['apple', 'banana', 'cherry'];

for (const fruit of fruits) {
  console.log(fruit.toUpperCase()); // 자동완성 도움을 받을 수 있음
}

 

< 에디터 메서드 자동완성 기능 >

fruit 타입이 string일 경우 사용가능한 메서드만 보여준다.

 

 

2. 객체 타입

 

타입스크립트에서는 객체의 구조와 속성을 명확하게 정의할 수 있다. 객체 타입을 정의하는 방법부터 옵셔널 속성, 읽기 전용 속성, 타입 별칭, 타입 추론까지 다양한 기능이 존재한다. 이 글에서는 객체 타입과 관련된 내용을 하나씩 정리한다.

 

 1) 객체 타입 정의

객체의 구조를 정의할 때는 : 기호를 사용해 각 속성의 이름과 타입을 명시한다. 예시는 아래와 같다.

let user: {
  name: string;
  age: number;
} = {
  name: "Alice",
  age: 25,
};

user 객체는 name 속성에 문자열, age 속성에 숫자가 들어간다.

 

 

 2) 선택적 프로퍼티 (Optional Property)

객체의 속성이 선택적일 경우 물음표(?)를 사용하여 정의할 수 있다.

type User = {
  name: string;
  age?: number; // 선택적 프로퍼티
};

이렇게 정의하면 age를 생략해도 오류가 나지 않는다.

 

 

3) 중첩 객체 타입

객체 안에 또 다른 객체가 포함된 구조를 중첩 객체(nested object)라고 한다.

타입 별칭을 사용하면 중첩된 구조도 명확하게 표현할 수 있다.


type Address = {
  city: string;
  zipCode: string;
};

type User = {
  name: string;
  address: Address;
};
  

User 타입의 address 프로퍼티는 Address 타입을 가진다.

이렇게 하면 코드의 가독성과 재사용성을 높일 수 있다.

중첩 객체는 직접 정의할 수도 있다.


type User = {
  name: string;
  address: {
    city: string;
    zipCode: string;
  };
};
  

이 경우 address의 구조는 한 번만 사용된다면 간단히 정의하는 데 적합하다.

 

 

 4) 타입 별칭 (Type Alias)

TypeScript에서 객체를 다룰 때 가장 많이 쓰는 기능 중 하나는 타입 별칭(type alias)이다. 타입 별칭은 type 키워드를 사용하여 타입에 이름을 붙이는 방식이다.

type User = {
  name: string;
  age: number;
};

위 예시는 User라는 타입 별칭을 정의한 것으로, 객체는 nameage 속성을 가진다.

 

 5) 읽기 전용 프로퍼티 (Readonly Property)

readonly 키워드를 사용하면 해당 프로퍼티는 수정할 수 없게 된다.

type User = {
  readonly id: number;
  name: string;
};

id는 초기값 설정 이후 변경이 불가능하다.

 

 6) 객체 타입과 선택적/읽기 전용 프로퍼티의 조합

type User = {
  readonly id: number;
  name: string;
  age?: number;
};

이렇게 조합하면, 객체는 id는 읽기 전용이고, age는 선택적으로 가질 수 있다.

 

 7) 타입 추론

타입스크립트는 변수에 명시적으로 타입을 지정하지 않아도 값을 통해 자동으로 타입을 추론할 수 있다.

const user = {
  name: 'Alice',
  age: 30,
};

위 예시에서 user의 타입은 자동으로 { name: string; age: number }로 추론된다.

 

 

3. 함수 타입(Function Types)

  1) 함수의 파라미터와 리턴 타입 지정

TypeScript에서는 함수의 파라미터와 리턴 타입을 명시적으로 지정할 수 있다.

function add(x: number, y: number): number {
  return x + y;
}

파라미터 xynumber 타입이며, 함수는 number를 반환한다.

 

  2) 선택적 파라미터 (Optional Parameters)

파라미터 뒤에 ?를 붙이면 선택적으로 받을 수 있다. 생략된 경우 undefined가 된다.

function log(message: string, userId?: string) {
  console.log(message, userId);
}

userId는 있어도 되고 없어도 되는 값이다.

 

  3) 기본값 파라미터 (Default Parameters)

파라미터에 기본값을 지정할 수 있다. 기본값이 있으면 자동으로 선택적 파라미터가 된다.

function log(message: string, userId = "Not signed in") {
  console.log(message, userId);
}

함수 호출 시 userId를 생략하면 "Not signed in"으로 설정된다.

 

  4) 함수의 반환 타입 명시

TypeScript는 기본적으로 타입 추론을 하지만, 명시적으로 지정하는 것이 코드 가독성과 유지보수에 도움이 된다.

function sum(a: number, b: number): number {
  return a + b;
}

 

  5) void 타입

리턴값이 없는 함수는 void 타입을 사용한다.

function printGreeting(): void {
  console.log("Hello!");
}

 

  6) never 타입

never는 함수가 절대 반환하지 않음을 의미한다. 예외를 던지거나 무한 루프일 때 사용된다.

function fail(message: string): never {
  throw new Error(message);
}

 

  7) 함수 표현식에서 타입 지정

함수를 변수에 할당할 때 타입을 함께 선언할 수 있다.

const multiply: (x: number, y: number) => number = (x, y) => x * y;

 

  8) 컨텍슈얼 타이핑 (Contextual Typing)

타입스크립트는 문맥을 통해 함수의 파라미터 타입을 추론할 수 있다.

콜백 함수에서 el 의 값은 string 타입을 추론 된다.

const names : string[] = ["Alice", "Bob", "Eve"];
names.forEach( (el) => {
  console.log(el.toUpperCase());
});

s는 자동으로 string 타입으로 추론된다.

 

 

아래 코드와 같이 타입 작성도 가능하지만 타입 정의에 시간을 쓰는것 보다 로직개발에 집중하자!

names.forEach( (el : string) => {   // 이런식으로 타입 작성도 가능하다.
  console.log(el.toUpperCase());
});

 

9) 나머지 파라미터(Rest Parameters)

여러 개의 파라미터를 배열 형태로 받을 수 있다.

function multiplyAll(multiplier: number, ...nums: number[]): number[] {
  return nums.map((n) => n * multiplier);
}

이 함수는 첫 번째 인자를 기준으로 나머지 숫자들을 모두 곱한 결과 배열을 반환한다.