ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2023 - 07 - 24 TypeScript 타입스크립트 const, readonly, any, unknown, union
    Today I Learned/TIL 07 2023. 7. 27. 10:50

    오늘 배운 것:

    타입스크립트 let, const, readonly, any, unknown, union

     

     

    let : 변수선언 (값을 변경할 수 있다.)

    let num: number = 5;
    console.log(num);  // 출력: 5
    
    num = 10;
    console.log(num);  // 출력: 10

     

    const: 상수선언 (값을 변경할 수 없다. 즉 =로 재할당할 수 없다.)

    const num: number = 5;
    console.log(num);  // 출력: 5
    
    num = 10;  // 에러: 'num'은 const로 선언되었으므로 다시 할당될 수 없음!
    const nums: number[] = [];
    console.log(nums);  // 출력: []
    nums.push(1); // 할당은 되지 않아도 배열에 데이터를 추가/삭제하는 것은 문제가 안됨
    nums.push(2); // 은근히 헷갈릴 수 있지만 = 연산자 기준으로만 생각하면 매우 쉬움
    console.log(nums);  // 출력: [1, 2]
    
    nums = [];  // 에러: 'nums'는 const로 선언되었으므로 다시 할당될 수 없다.

     

    앞의 let과 const는 자바스크립트에서 많이 사용되는 키워드이지만,

    readonly는 타입스크립트에서 등장한 키워드이다. 

     

    readonly는 타입스크립트에서 객체의 속성을 불변으로 만드는 데 사용되어서,

    클래스의 속성이나 인터페이스의 속성을 변경할 수 없게 만들 수 있다.

     

    class Person {
      readonly name: string;   //  readonly를 통해 name의 타입을 string으로 정의함
      readonly age: number;  //  readonly를 통해 age의 타입을 number로 정의함
    
      constructor(name: string, age: number) {  // constructor 생성자를 통해 객체의 속성을 불변으로 만듦
        this.name = name;  
        this.age = age;
      }
    }
    
    const person = new Person('Spartan', 30);
    
    console.log(person.name);  // 출력: 'Spartan'
    console.log(person.age);   // 출력: 30
    
    person.name = 'Jane';  // 에러: 'name'은 readonly 속성이므로 다시 할당할 수 없다
    person.age = 25;       // 에러: 'age'은 readonly 속성이므로 다시 할당할 수 없다

     


    1. any, unknown, union

    어쩔 수 없이 가변적인 타입의 데이터를 저장하고 싶다면 any보다는, unknown을 쓰는 것이 좋고,

    가변적인 타입을 일일이 정의할 수 있다면 union 사용이 가장 낫다.

     

    - any는 모든 타입에 쓰일 수 있는 슈퍼 타입으로써, 자바스크립트의 object 타입과 같은 최상위 타입이다.

    하지만, any 타입은 코드의 안정성과 유지 보수성을 저해할 수 있으므로, 가급적 사용하지 말아야 한다.

    let anything: any;
    anything = 5; // 최초에는 숫자를 넣었지만
    anything = 'Hello'; // 문자열도 들어가고
    anything = { id: 1, name: 'John' }; // JSON도 들어간다. (바람직하지 않음)

     

    -any의 대체제 unknown

    unknown 타입은 any 타입과 비슷한 역할을 하지만 더 안전한 방식으로 동작한다.

    unknown 타입의 변수에도 모든 타입의 값을 저장할 수 있다. 하지만, 그 값을 다른 타입의 변수에 할당하려면 typeof 등으로 명시적으로 타입을 확인해야 한다.

     

    let unknownValue: unknown = '나는 문자열입니다';
    console.log(unknownValue); // 나는 문자열입니다!
    
    let stringValue: string;
    stringValue = unknownValue; // 에러 발생! unknownValue가 string임이 보장이 안되기 때문!
    stringValue = unknownValue as string;
    
    console.log(stringValue); // 나는 문자열입니다!

    stringValue = unknownValue as string; 코드를 Type Assertion (타입 단언)이라고 한다.

    unknown 타입의 변수를 다른 곳에서 사용하려면 타입 단언을 통해 타입 보장을 해서 사용할 수 있다.

     

    let unknownValue: unknown = '나는 문자열입니다!';
    let stringValue: string;
    
    if (typeof unknownValue === 'string') {
      stringValue = unknownValue;
      console.log('unknownValue는 문자열이네요~');
    } else {
      console.log('unknownValue는 문자열이 아니었습니다~');
    }

     

    이러한 unknown도 재할당을 할 때 타입 체크가 되므로 안전함을 보장한다. 하지만, unknown 타입도 결국 재할당이 일어나지 않으면 타입 안정성이 보장되지 않는다.

    이럴 때를 위해 union 타입이라는 것이 사용된다. union은 여러 타입 중 하나를 가질 수 있는 변수를 선언할 때 사용되며, union은 | 연산자를 사용해 여러 타입을 결합하여 표현한다.

     

    type StringOrNumber = string | number; // 원한다면 | boolean 이런식으로 타입 추가가 가능하다
    
    function processValue(value: StringOrNumber) {
      if (typeof value === 'string') {
        // value는 여기서 string 타입으로 간주된다.
        console.log('String value:', value);
      } else if (typeof value === 'number') {
        // value는 여기서 number 타입으로 간주된다.
        console.log('Number value:', value);
      }
    }
    
    processValue('Hello');
    processValue(42);

    댓글

Designed by Tistory.