TypeScript: Basic Types Ep.3 (string,symbol,null & undefined, object, array, tuple)

string


텍스트 형식을 참조하기 위해 ‘string’ 형식을 사용한다.

let name: string = "mark";

name = 'anna';
  • Template String

    행에 걸쳐 있거나, 표현식을 넣을 수 있는 문자열이다. 이 문자열은 backtick() 기호에 둘러쌓여 있다.

    let fullName: string = `Bob Bobbington`
    let age: number = 30;
      
    let sentence: string = `Hello, my name is ${ fullName}.
    I'll be ${ age + 1 } years old next month.`;
    
    • Template string을 사용하지 않을 경우
      let sentence: string = "Hello, my name is " + fullName + ".\n\n" + "I'll be" + (age + 1) + "years old next month.";
      

symbol


ECMAScript 2015의 Symbol이다.
new Symbol로 사용할 수 없다.
Symbol을 함수로 사용해서 symbol 타입을 만들어 내서 사용한다.

console.log(Symbol('foo') === Symbol('foo'));
// false

같은 함수의 같은 인자를 넣어도 독립적으로 완전히 다르기 때문에 둘이 동일한지 물어보면 동일하지 않다고 말하는 것이다.

  • Symbol 사용

    프리미티브 타입의 값을 담아서 사용한다.
    Symbol로 인해 생성된 값은 고유하고 수정 불가능한 값으로 만들어준다.
    그래서 주로 접근을 제어하는데 사용하는 경우가 많다. (문자열만 사용해서 접근할 때 사용할 수 없고 꼭, 심볼을 얻어야만 사용할 수 있도록 할때 사용하는 경우가 많다.)

    const sym = Symbol()
      
    const obj = {
      [sym]: "value"
    };
      
    console.log(obj[sym]); // "value"
    
  • 주의!

    함수로 사용할 때는 대문자 심볼 Symbol
    (함수 심볼로 인해 만들어진)타입으로 사용할 때는 소문자 심볼 symbol

null & undefined


  • null

    null 이라는 값으로 할당 된 것을 null이라고 한다.
    null은 무언가 있는데 사용할 준비가 덜 된상태를 말한다.
    null 타입은 null이라는 값만 가질 수 있다.
    런타임에서 typeof 연산자를 사용해보면 object라고 나온다.

    let n: null = null;
      
    console.log(n);  // null
    console.log(typeof n); // object
    
  • undefined

    undefined는 값을 할당하지 않은 변수의 값이다.
    undefined는 무언가가 아예 준비가 안된 상태이다.
    object의 property가 없을 때에도 undefined이다.
    typeof 연산자를 사용하면 undefined라고 나온다.

    let u: undefined = undefined;
      
    console.log(u); // undefined
    console.log(typeof u); // undefined
    
  • null과 undefined

    각각 unll, undefined라는 타입을 가지며 void같이 그 자체로는 유용하지 않다.
    null과 undefined는 타입과 값 모두 소문자로 작성해야 한다.

    let u: undefined = undefined;
    let n: null = null;
    // 해당 변수에 할당할 수 있는 것들이 거의 없다.
    
    • 설정을 통해 유용하게 사용하기

      null과 undefined는 다른 모든 타입의 서브타입으로 존재한다.
      설정을 통해 number에 null 또는 undefined를 할당할 수 있게 된다.
      그런데, 컴파일 옵션에서 --strictNullChecks 사용하면, 다른 모든 타입의 서브타입으로 사용할 수 없게 된다. 즉, null과 undefined는 void나 자기 자신들에게만 할당할 수 있게 된다.
      반대로, null과 undefined를 할당할 수 있게 하려면 union type을 이용해야 한다.

      • strictNullChecks => false (끄기)

        null, undefined 사용가능

        let name: string = null;
        let age: number = undefined;
        
      • strictNullChecks => true (키기) 혹은 strict == true
        let name: string = null; (x)
        // Type 'null' is not assignable to type 'string'
        
        let u: undefined = null; // (x)
        // Type 'null' is not assignable to type 'undefined'
              
        let nu: null = null; // (o)
        
        // void의 값으로는 오로지 undefined만 가능. null, void는 불가
        let v: void = undefined; // (o)
        
      • strictNullChecks => true 상태에서 primitive type 사용하기

        union 형태로 작성하면 사용이 가능하다.

        let union: string | null | undefined = 'str'; // union 형태
        

object


우리가 흔히 아는 object와 typescript의 object는 약간 다르다.
typescript의 object는 primitive type이 아닌 것이다. 즉, primitive 타입을 사용할 수 없는 곳에는 object를 사용한다고 생각하면 된다.
(primitive type ⇒ number, string, boolean, bigint, symbol, null, or undefined)
단, null은 object로 사용 가능 (null 설명 참고)

let obj: object = {};

obj = {name: 'Mark'};
obj = [{name: 'Mark'}];
obj = 39; // Error
obj = Mark; // Error
obj = true; // Error
obj = 100n; // Error
obj = Symbol(); // Error
obj = null; // Error
obj = undefined; // Error
declare function create(o: object | null): void;
// primitive type을 넣으면 Error을 뱉어낸다.

create({ prop: 0});
create(null);
create(42); // Error
crate("string"); // Error
crate(false); // Error
crate(undefined); // Error

// Object.create
Object.create(o); // Error
  • 오브젝트 리터럴 (object literal)
    const person1 = {name: 'Mark', age: 39};
      
    // person1 is not "object" type.
    // person1 is "{name: 'Mark', age: 39}" type.
    
  • 전역개체 Object
    const person2 = Object.create({name: 'Mark', age: 39});
      
    const person3 = Object.create(39) // 사용불가
    

    Object라는 전역개체를 통해 .create를 하면 안에 들어있는 오브젝트 리터럴을 통해 객체를 만들어 낸다.

    Object.create 함수 안에 object type의 형태를 넣어야 한다. 즉, primitive type이 아닌 것을 넣어야 한다.
    따라서 해당 함수의 인자에는 object 타입이거나 null을 넣을 수 있다.

Array


object의 일종이며, 같은 타입의 자료형을 모아둔 것을 의미한다.
주의할 점은, 배열 안의 요소들은 동일한 타입이어야 한다. 하나의 타입으로 묶을 수 없다면 array가 아닌 것이다.

  • array를 표현하는 두가지 방법
    // 선호하는 방법
    let list: number[] = [1, 2, 3];
      
    let list: Array<number> = [1, 2, 3];
    
  • 다른 타입의 요소들 사용하기

    또는 ( | )을 사용하여 타입이 다른 요소들을 하나로 묶는다.
    따라서, 각 요소들은 number이거나, string이다.
    해당 방법은 요소들이 무슨 타입인지 정확히 모를때에도 사용할 수 있다.

    let list: (number | string)[] = [1, 2, 3, "4"];
    
  • 타입을 정확히 알고 있을 때 (tuple)

    첫번째 타입이 무엇이고 두번째 타입이 무엇인지 정확히 알고 있을 때가 있다. 그럴때는 array가 아닌, tuple을 사용한다.

    [39, "Mark"];
    

Tuple


앞, 뒤로 다른 타입을 넣고 싶을 때, 그런데 해당 타입들이 오는 순서를 알고 있을 때 사용한다. 단, 항상 타입과 순서, 길이가 맞아야 한다.

let x: [string, number];

x = ['hello', 39];

x = [20, 30]; // Error, 타입 안 맞음
x = [10, 'anna']; // Error, 순서 안 맞음
x[2] = 'world'; // Error, 길이 안 맞음
  • 구조분해할당(destructuring)을 해도 해당 타입이 정해져 있다.
    const person: [string, number] = ["mark", 39];
      
    const [first, second] = person; 
    // first = string, seconed = number
      
    const [first, second, third] = person; // Error, 길이 안 맞음
    

Comments