front-end/TypeScript

[TypeScript] 기본타입 (union, literal, typeAlias)

Ash_O 2023. 8. 6. 19:21

Union

문자열이나 숫자를 인자로 두개 받아서 두 값을 합하는 함수를 작성하려 한다.

즉, 반환은 문자열일수도 있고 숫자일수도 있다.

함수의 기능은 문자열 연결도 되고 숫자 연산도 되어야 한다.

이때 union타입을 사용할 수 있다.

function combine(input1: number|string, input2: number|string){
  const result = input1 + input2;
  return result;
}

위 코드는 문제가 있다

-> '+' 연산자를 'string | number' 및 'string | number' 형식에 적용할 수 없습니다.

 

즉, string | number 타입 자체를 union이라고 이해는 하지만, 어떤 타입들이 모여 Union을 이루고 있는지는 분석하지 않는다.

 

그래서 이때 type guard를 이용해서 함수를 완성시킬 수 있다.

function fixCombineWithUnion(input1: number | string, input2: number | string) {
  let result;
  if (typeof input1 === "number" && typeof input2 === "number") {
    result = input1 + input2;
  } else {
    result = input1.toString() + input2.toString();
  }
  return result;
}

이런식으로 런타임에 타입검사를 시행하는 것을 타입가드라고 한다.

프로그램에 따라 유니온타입을 사용하게 되면 필요하게 될 수 있다.

유니온 타입을 사용하면, 코드에 적용한 매개변수를 보다 유연하게 사용할 수 있다.

타입에 따라 함수 내에서 다양한 로직을 적용할 수 있어서 함수가 여러 타입의 값으로 작동이 가능하다.


literalType

리터럴 타입은 특정 변수나 매개변수가 아니라, 값 자체를 타입으로 지정하는 것이다.

아래 코드는 할당된 값 자체가 타입으로 추론된다.

const number = 5;
// const number: 5

문자열 리터럴 타입의 경우 유용하게 사용될 수 있는데,

combine 함수를 아래처럼 만들 수 있다.

type inputType = number | string
type resultType = "as-number" | "as-text"

function Combine(input1: inputType, input2: inputType, resultType: resultType) {
  let result;
  if ((typeof input1 === "number" && typeof input2 === "number") || resultType === "as-number") {
    result = +input1 + +input2;
  } else {
    result = input1.toString() + input2.toString();
  }
}

resultType에 따라 반환되는 타입을 조정하는 로직을 추가했다.

물론 enum으로 해결할 수 있지만, 지금은 종류가 많지 않으니 리터럴 타입의 사용을 고려해볼 수 있다.

개발자가 해당 값을 기억해야한다는 단점이 있지만, resultType의 값을 문자열이 아닌 더 좁은 범위의 값들로만 제한시켜

허용되는 값을 지정할 수 있다.

 

이렇게 했을때, 타입에 어긋나는 값을 사용하게 되면 에러로 지적해준다.

Combine(1,2,"ab");
// '"ab"' 형식의 인수는 '"as-number" | "as-text"' 형식의 매개 변수에 할당될 수 없습니다.

TypeAlias

위 예제 코드에서, inputType과 resultType을 변수처럼 선언하여 사용하고 있다.

반복되는 코드를 계속 사용하는 것은 번거로운 일이니 타입을 저장할 수 있는 새로운 타입을 변수처럼 만들어서 사용하는 것을
TypeAlias라고 한다.

 

type typename = someComplexTypes;

 

이를 사용하면, 복잡한 타입 정의를 원하는 자신만의 타입 이름으로 인코딩해두었다가 필요할 때 사용할 수 있다.

type User = {
    name: string; 
    age: number;
}
const u1: User = {name:'Max', age: 30}

  // 이렇게 하면 불필요한 반복을 피하고 타입을 관리할 수 있다.

function greet(user: {name: string; age: number}){
    console.log(user.name)
}
function isOlder(user: {name: string; age: number}, checkAge:number){
    return checkAge > user.age
}

  // 위 처럼 돼있는걸 단순화 할 수 있음

function greetTypeAlias(user: User){
    console.log(user.name)
}
function isOlderTypeAlias(user: User, checkAge:number){
    return checkAge > user.age
}

 


reference : 유데미 타입스크립트 강의

https://www.udemy.com/course/best-typescript-21/