본문 바로가기

[코딩애플] Type Alias / readonly

codeConnection 2024. 6. 25.

Type Alias

타입의 별칭을 정하는 것이다.

타입이 너무 길 때 사용하면 더 좋다.

 

기본적인 사용법은 아래와 같다.

  • type 파스칼케이스별칭 = 자료형;
  • const 변수명: 파스칼케이스별칭 = 값;

일반 변수

// 일반 변수
type Username = string;
type Age = number;

let userName: Username = '장원영';
let userAge: Age = 25;

 

객체 타입

기본 사용법

일반 변수는 짧아서 타입의 별칭을 지어주는 것이 매력적으로 느껴지지 않을 수 있지만 이제부턴 상황이 다르다.

먼저 객체 타입은 데칼코마니로 타입을 지정해준다는 것이 기억날 것이다.

const user = {
  name: '장원영',
  age: 21,
  job: '가수',
  isFemale: true
}

 

위와 같은 객체가 있을 때 자료형은 그대로 복사해서 value만 타입을 지정해주면 된다.

const user: {
    name: string,
    age: number,
    job: string,
    isFemale: boolean
  } = {
    name: '장원영',
    age: 21,
    job: '가수',
    isFemale: true
  }

 

보기만 해도 길고 복잡하고 끔찍하다. 위의 예제도 프로퍼티가 네 개 뿐이라 그렇지 객체 안에 배열이 있고 그 배열 안에 객체가 있는 이런 중첩된 자료구조에서는 더 복잡하게 느껴질 것이다.

 

이것을 type alias로 별칭을 만들어 주면 아래와 같다.

type User = {
    name: string;
    age: number;
    job: string;
    isFemale: boolean;
  }

const user: User = {
    name: '장원영',
    age: 21,
    job: '가수',
    isFemale: true
  }

 

참고로 객체의 프로퍼티를 구분할 때 세미콜론이나 콤마나 똑같다. 취향 차이이다.

중첩된 객체에서의 사용법

더 복잡하게 객체가 중첩된 형태도 type alias로 설정 가능하다.

// 자바스크립트 원 객체

let person = {
  name: '장원영',
  age: 21,
  address: {
    street: "을지문덕로 123",
    city: "서울",
    country: "대한민국"
  },
};

// 타입스크립트 타입 명시

let person: {
  name: string,
  age: number,
  address: {
    street: string,
    city: string,
    country: string
  },
}
= {
  name: '장원영',
  age: 21,
  address: {
    street: "을지문덕로 123",
    city: "서울",
    country: "대한민국"
  },
};

// Type Alias 설정

type Address = {
  street: string,
  city: string,
  country: string
}

type Person =  {
  name: string,
  age: number,
  address: Address
};

let person: Person = {
  name: '장원영',
  age: 21,
  address: {
    street: "을지문덕로 123",
    city: "서울",
    country: "대한민국"
  },
};

 

중첩된 객체도 가장 deps가 깊은 것부터 쪼개어 type alias를 설정해주니 가독성이 더 좋아졌으며 작은 단위로 쪼개 놓았기 때문에 유지보수에도 용이하고 재사용성도 높아진다.

객체의 재사용 하는 type alias에서 특정 프로퍼티가 옵션인 경우

type Squere = {
  width : number,
  height : number,
  color? : string
}

const firstSquere: Squre = {
  width: 100,
  height: 100,
  color: 'red'
}

const secondSquare: Squre = {
  width: 200,
  height: 150
}

 

위에서 Squre라는 type alias는 여기저기서 재사용되고 있는데, color라는 프로퍼티는 있을 수도 있고 없을 수도 있는 프로퍼티라고 하면 key에 ? 물음표를 붙여 주면 된다.

즉 값이 없을 수도 있다, undefined일 수도 있다고 알려주는 것이다.

 

color? : string 은 color: string | undefined와 같은 식이다.

Union type

어떤 자료형이 올 지 몰라 여러 자료형의 가능성을 두는 유니언 타입도 alias를 만들어 두면 편리하다.

const userId = "wonyoung1004";
const anotherUserId = 1004;

 

위 예시를 보면 둘 다 ID를 나타내지만 하나는 string이고 하나는 number type이다.

 

const userId: string = "wonyoung1004";
const anotherUserId: number = 1004;

 

매번 이렇게 지정해줘도 되지만, 이러한 변수가 수 백개가 되고, string이나 number 중 어떤 게 값으로 올 지 매번 예측할 수 없다고 하면 union type으로 유연성을 부여하는 것도 좋다.

 

const userId: string | number = "wonyoung1004";
const anotherUserId: string | number = 1004;

 

아까처럼 모든 변수마다 자료형을 명시해주는 것보다 string | number 를 복붙해서 사용하면 되기 때문에 더 나아졌다.

하지만 계속 반복되니, 이것을 type alias로 할당하고 꺼내어 쓰면 더 편할 것 같다.

 

type ID = string | number;

const userId: ID = "wonyoung1004";
const anotherUserId: ID = 1004;

readonly

자바스크립트에서 변수를 선언할 때 사용하는 키워드로는 const, let, var가 있다. var는 변수의 재선언이 가능한 이상한 키워드이기 때문에 현재는 레거시로 판단하고 있다.

 

const와 let은 변수의 재선언은 불가능하지만, let은 변수의 재할당은 가능하고 const는 재할당이 불가능하다.

 

그런데 const가 일반 자료형이 아니라 객체 타입일 때는 객체 내부의 값을 점 표기법으로 바꿀 수가 있다.

// 자바스크립트에서 이건 안 됨.
const person = '장원영';
person = '안유진';

// 그런데 이건 됨.
const person = {
  name: '장원영',
  age: 21
}

person.name = '안유진';

 

이렇게 점 표기법으로 객체의 값을 바꿀 수 있는 것을 막을 수 있는 기능이 readonly 즉 읽기 전용이다.

사용법은 간단하다. type alias의 앞에 붙이면 된다.

 

type Person = {
  readonly name: string,
  age: number
}

const person = {
  name: '장원영',
  age: 21
}

person.name = '안유진'; // 에러
person.age = 31; // 가능

 

배열에서도 readonly를 명시하면 대괄호 표기법, push와 같은 배열 전용 메서드로 배열의 원본 값을 수정할 수 없다.

 

const numbers: readonly number[] = [1, 2, 3, 4, 5];

numbers[0] = 100; // 에러
numbers.push(6); // 에러

type alias 병합하기

type Name = string;
type Age = number;

// 아래 두 개는 같은 의미다.
type NewOne = Name | age;
type NewOne = string | number;

 

위처럼 원시 타입 자료형 말고 아래처럼 객체도 병합할 수 있다. & 기호를 사용해서 병합하면 된다.

 

type PositionX = { x : number };
type PositionY = { y : number };

type XandY = PositionX & PositionY;

const location: XandY = { x : 1, y : 2 }

 

 

이런 것 뿐만 아니라 직접적으로 붙이는 것도 가능하다.

 

type PositionX = { x : number };
type NewOne = PositionX & { y : number };

// 아래와 같은 식이다.
type NewOne = { x : number, y : number };

 

type 키워드는 재정의 불가능

type Name = string;
type Name = number;

 

type 키워드는 위와 같은 것이 안 된다.

다만 추후 배울 interface에서는 가능하다. 하지만 타입스크립트의 장점이 엄격한 데이터 비교에 있는데 부득이한 경우가 아니고서야 굳이 유연성을 부여하면서 자바스크립트처럼 사용할 이유는 부족하다.

댓글