TS/[책] 타입스크립트 프로그래밍

3장. 타입의 모든 것

배워도끝이없네 2021. 11. 26. 22:11

3.1 타입의 가나다

  1. any
    • any는 모든타입을 허용한다.
    • 가급적 사용하지 않아야 한다.
    • 타입스크립트의 기본 설정은 자유를 허용하므로 any로 추론되는 값을 발견해도 예외를 발생시키지 않는다. 암묵적 any를 예외처리 하고싶다면 tsconfig.json파일에서 noImplicitAny플래그를 활성화하면 된다.
  2. unknown
    • 타입을 미리 알 수 없는 어떤값이 있다면 any대신 unknown을 사용하자.
    • unknown도 모든 값을 대표하지만, 타입을 검사해 정제하기 전까지는 타입스크립트가 unknown 타입의 값을 사용할 수 없게 강제한다.
    • unknown은 비교연산과 !를 지원하고 typeof, instanceof로 정제할 수 있다.
  3. boolean
    • true와 false를 가진다.
    • 타입스크립트에게 어떤값이 boolean인지 여러방법을 이용해 알려줄 수 있다.
      1. let a = true  // boolean
      2. var b = false // boolean
      3. const c = true // true
      4. let d: boolean = true // boolean
      5. let e: true = true // true
      6. let f: true = false //타입에러
    • boolean타입이 가질수 있는 값중 특정한 값 하나로 한정하는 기능을 타입 리터럴이라고 한다.
  4. number
    • number는 숫자의 집합이다.
  5. bigint
    • number는 2의 53승까지 정수를 표현할 수 있지만 bigint는 이것보다 큰 숫자도 지원한다.
  6. string
    • 문자열의 집합으로 연결(+), 슬라이스 등의 연산을 수행할 수 있다.
  7. symbol
    • 실무에서는객체와 맵에서 키를 대신하는 용도로 사용된다.
    • unique symbol타입은 반드시 const여야 한다.
  8. 객체
    • object타입은 any보다 조금 더 좁은 타입이다.
    • 서술하는 값에 관한 정보를 거의 알려주지 않으며, 값 자체가 객체라고 말해줄 뿐이다.
      • let c: {
        	firstNmae: string,
        	lastName: string
        } = {
        	firstName:"jone",
            lastName: "barrowman"
        }
        
        class Person{
        	constructor(public firstName: string, public lastName: string){ //public은 this.firstName = firstName을 축약한것
            	
            }
        }
        
        c = new Person('matt', 'smith') // OK
    • 타입스크립트는 객체프로퍼티에 엄격해 정의된 객체에 대해 없는 추가 프로퍼티가 있거나 지정된 프로퍼티가 존재하지 않으면 에러를 발생시킨다.
    • 이를위해서 다음과 같이 작성하면 타입스크립트에게 추가될수 있도록 고지할 수 있다.
    • let a: {
      	b: number,
          c?: string,
          [key: number]: boolean
      }
    • a는 number타입의 b를 보함하고, c는 포함할 수도 있으며, boolean타입을 갖는 number타입의 프로퍼티를 여러개 가질 수도 있다.
    • 객체 타입을 정의할때 선택형(?) 만 사용할수 있는것은 아니다. 필요시 readonly 한정자를 이용해 특정필드를 읽기 전용으로 바꿀 수 있다(프로퍼티에 const를 적용한것과 같은 효과)
    • 빈객체타입이라는 상황도 존재하지만 가능한 피하는것이 좋다 let danger: {}
    • 객체: Object로 객체 타입을 만드는 방법도 가급적 사용을 피하는것이 좋다.
    • 타입스크립트에서 객체를 정의하는방법을 요약하면 다음과 같다
      1. 객체 리터럴 표기법 {a: string}. 객체가 어떤 필드를 포함할수 있는지 알고있거나 객체의 모든값이 같은 타입을 가질 때 싸용.
      2. 빈 객체 리터럴 표기법 {}. 이 방법은 사용하지 않는 것이 좋다.
      3. objct타입. 어떤 필드를 가졌는지 관심 없고 단지 객체가 필요할 때 사용된다.
      4. Object타입. 사용하지 않는것이 좋다.
  9. 타입별칭, 유니온, 인터섹션
    • 타입별칭
      1. 타입별칭으로 타입을 가리킬 수 있다.
        type Age = number;
        type Person = {
        	name:string,
            age: Age
        }
      2. 타입스크립트는 타입 별칭을 추론하지 않으므로 반드시 별칭의 타입을 명시적으로 정의해야 한다.
      3. 하나의 타입을 두번 정의할 수는 없다.
    • 유니온과 인터섹션 타입
      1. A, B집합에서 이를 합집합(유니온) 하면 둘을 합친 전부의 결과가 나오며, 교집합(인터섹션)하면 둘의 공통부분이 결과로 나온다.
      2. TS는 타입에 적용할 수 있는 연산자인 ( | ) 유니온과 ( & ) 인터섹션을 제공한다.
      3. 타입은 집합과 비슷하므로 집합처럼 연산을 수행할 수 있다.
      4. type Cat = {name: string, purrs: boolean};
        type Dog = {name: string, barks: boolean, wags: boolean};
        type CatAndDog = Cat & Dog
        type CatOrDogOrBotg = Cat | Dog
      5. 실전에서는 인터섹션보다 유니온을 자주 사용한다.
  10. 배열
    • 타입스크립트 배열도 concat, push, search, slice등을 지원하는 객체이다.
    • 타입스크립트는 T[]와 Array<T>라는 두가지 배열 문법을 지원한다. 성능, 의미상 두 표현은 같다.
    • 타입스크립트의 배열은 모든 항목이 같은 타입을 갖게 하려고 노력한다.
  11. 튜플
    • 튜플은 배열의 서브타입이다.
    • 길이가 고정되었고 각 인덱스의 타입이 알려진 배열의 일종이다.
    • 튜플은 선언할 때 타입을 명시해야 한다.
    • let a: [number] = [1]
      
      let b: [string, string, number] = ['malcolm', 'gladwell', 1963]
      
      //튜플은 선택형 요소도 지원한다.
      
      let trainFares: [number, number?][] = [
      	[3.85],
          [8.25,7.70],
          [10.50]
      ]
      
      // 스프래드 연산자를 이용해 나머지요소를 나타낼 수 있다.
      let friends: [string, ...string[]] = ['sara', tali, 'chloe', 'claire'];
      
      let list: [number, boolean, ...string[]] = [1,flase, 'a', 'b', 'c'];
    • 튜플은 이형 배열을 안전하게 관리할 뿐만 아니라 배열타입의 길이도 조절하기 때문에 튜플 사용을 권장한다.
    • 읽기 전용 배열과 튜플
      • 일반 배열은 가변인 반면 typescript는 readonly배열타입을 기본으로 지원해 불변 배열을 만들 수 있다.
      • let as: readonly number[] = [1,2,3] //readonly number[];
        let bs: readonly number[] = as.concat(4) //readonly number[];
        let three = bs[2]
        as[4] = 5 // 읽기전용이라 TS2542에러
        
        type A = readonly string[] //readonly string[]
        type B = ReadonlyArray<String> // readonly string[]
        type C = Readonly<string[]> // readonly string[]
  12. null, undefined, void, never
    • 타입스크립트는 null과 undefined 이외에도 void 와 never타입도 제공한다.
    • void는 명시적으로 아무것도 반환하지 않는 함수의 반환타입을 가리킨다.
    • never는 절대 반환하지 않는(예외or 무한루프) 함수타입을 가리킨다.
    • unknown이 모든 타입의 상위 타입이라면, never은 모든 타입의 서브타입이다.
    • 타입 의미
      null 값이 없음
      undefined 아직 값을 변수에 할당하지 않음
      void return문을 포함하지 않는 함수
      never 절대 반환하지 않는 함수
  13. 열거형
    • 열거형(enum)은 해당 타입으로 사용할 수 있는 값을 열거하는 기법이다.
    • 키를 값에 할당하는, 순서가 없는 자료구조이다.열거형의 이름은 단수 명사로 쓰고, 첫 문자는 대문자로 하는것이 관례이다.
    • 키도 앞 글자를 대문자로 표시한다.
    • 타입스크립트는 자동으로 열거형의 각 멤버에 적절한 숫자를 추론해 할당하지만, 값을 명시적으로도 설정할 수 있다.
    • enum Language {
      	English,
          Spanish,
          Russian
      }
      
      enum Language {
      	English = 0,
          Spanish = 1,
          Russian = 2
      }
      
      enum Color {
      	Red = "#c10000"
          Blue = "#007ac1"
          White = 255
      }
      
      let red = Color.Red // Color
    • 열거형에 문자열 값을 사용하거나 문자열과 숫자 값을 혼합할 수 있다.
    • const enum을 이용하면 타입스크립트의 안전하지 않은 접근을 막을 수가 있다.
    • const enum을 사용할 때에는 채워 넣긱 기능을 되도록 피해야 하며 npm으로 배포하거나 라이브러리로 제공하는 프로그램에서는 const enum을 사용하지 말아야 한다.
    • 열거형을 안전하게 쓰는 방법은 까다로우므로 열거형을 멀리하자!