TypeScript - type

eunung·2022년 7월 17일
0

TypeScript

목록 보기
2/7
  • 타입 : 값과 이 값으로 할 수 있는 일의 집합

    • Boolean
      : 모든 Bool(true, false)와 Bool에 수행할 수 있는 모든 연산(||, &&, ! 등)의 집합
    • number
      : 모든 숫자와 숫자에 적용할 수 있는 모든 연산(+, -, *, /, %, ||, &&, ? 등), 숫자에 호출할 수 있는 모든 메서드(.toFixed, .toPrecision, .toString 등)의 집합
    • String
      : 모든 문자열과 문자열에 수행할 수 있는 모든 연산(+, ||, && 등), 문자열에 호출할 수 있는 모든 메서드(.concat, .toUpperCase 등)의 집합
  • 타입스크립트의 타입 계층

    [출처] https://www.oreilly.com/library/view/programming-typescript/9781492037644/ch03.html


  • 타입 종류

    • any
      : 타입들의 대부
      : any로 무엇이든 할 수 있지만 꼭 필요한 상황이 아니라면 사용하지 않는 것이 좋음
      => 값이 자바스크립트처럼 동작하므로 타입스크립트를 사용하는 의미가 없어짐
      : 꼭 필요하다면 any를 명시적으로 선언하는 것이 좋음

      		let a: any = 666			// any
      		let b: any = ['danger']		// any
       	    let c = a + b				// any
      	💚 TSC 플래그: noImplicitAny
        	 : 암묵적인 any가 나타났을 때 예외를 일으키고 싶다면 활성화
         	 : stric을 활성화 했다면 따로 활성화할 필요 x
         
    • unknown
      : 타입을 미리 알 수 없는 어떤 값이 있을 때 any 대신 사용
      : 모든 값을 대표하지만, unknown의 타입을 검사해 정제하기 전까지는 타입스크립트가 해당 값을 사용할 수 없게 강제함.

      • 정제 방법: typeof, instanceof

      • 지원 연산: 비교 연산(==, ===, ||, &&, ?), 반전(!)

        let a: unknown = 30				// unknown
         let b = a === 123					// boolean
         let c = a + 10						// ERROR: 객체의 타입이 'unknown'
         if (typeof a === 'number') {
           let d = a + 10					// number
         }
      • boolean
        : true(참), false(거짓) 두 개의 값을 가짐
        - 지원 연산: 비교 연산(==, ===, ||, &&, ?), 반전(!)

         let a = true					// boolean
          var b = false					// boolean
          const c = true				// true
          let d: boolean  = true		// boolean
          let e: true = true			// true
          let f: true = false			// Error: 'false' 타입을 'true' 타입에 할당할 수 없음

        => c, e: 타입리터럴

        🧡 타입 리터럴
        : 오직 하나의 값을 나타내는 타입

    • number
      : 모든 숫자(정수, 소수, 양수, 음수, Infinity, NaN 등)

      • 지원 연산: 숫자 관련 연산(+, - , %, < 등)

        💚 긴 숫자를 처리할 떄는 숫자 분리자를 이용해 숫자를 읽기 쉽게 만들 수 있음
        => 타입과 값 모두에 사용 가능

         let oneMillion = 1_000_000 		// 1000000과 같음
          let twoMillion: 2_000_000 = 2_000_000
    • bigint
      : 자바스크립트와 타입스크립트에 새로 추가된 타입
      : 라운딩 관련 에러 걱정 없이 큰 정수 처리 가능
      : number는 253까지의 정수 표현 가능, bigint는 이보다 큰 수도 표현 가능

      let a = 1234n			// bigint
      const b = 5678n			// 5678n
      var c = a + b			// bigint
      let d = a < 1234		// boolean
      let e = 88.5			// Error: bigint 리터럴은 반드시 정수여야 함
      let f: bigint = 100n	// bigint
      let g: 100n = 100n		// 100n
      let h: bigint = 100		// Error: '100' 타입은 'bigint' 타입에 할당할 수 없음
    • string
      : 모든 문자열의 집합

      • 지원 연산: 연결(+), 슬라이스(.slice)
    • symbol
      : ES2015에 새로 추가된 기능
      : 실무에서는 자주 사용하지 않는 편, 객체와 맵에서 문자열 키를 대신하는 용도로 사용

      let a = Symbol('a')					// symbol
      let b: symbol = Symbol('b')				// symbol
      var c = a === b							// boolean
      let d = a + 'x'							// Error: '+' 연산을 'symbol' 타입에 적용할 수 없음
      const e = Symbol('e')					// typeof e
      const f: unique symbol = Symbol('f')	// typeof f
      let g: unique symbol = Symbol('f')		// Error: 'unique symbol' 타입은 반드시 'const'여야 함
      let h = e === e							// boolean
      let i = e === f							// Error: 'unique symbol' 타입은 서로 겹치는 일이 없으므로 결과는 항상 'false'
      - Symbol('a')는 주어진 이름으로 새로운 symbol을 만든다는 의미
       - 만들어진 symbol은 고유하여 다른 symbol과 == 또는 ===로 비교했을 때 같지 않다고 판단
    • 객체
      : 객체의 형태를 정의
      - 자바스크립트의 객체는 구조 기반 타입을 갖도록 설계되어 있음
      : 객체의 이름에 상관없이 객체가 어떤 프로퍼티를 갖고 있는지를 따짐

      // 방법1)
      let a: object = {
      	b: 'x'
      }
      a.b 			// Error: 'b' 프로퍼티는 'object'에 존재하지 않음
      
      // 방법2)  - 추론
      let a = {
      	b: 'x'
      }				// {b: string}
      a.b			// string
      
      let b = {
       	c: {
          	d: 'f'
        	}
      }				// {c: {d: string}}
      
      // 방법3) - 객체 리터럴
      let a: { b: number } = {
       	b: 12
      }				// {b: number}
      
      class Person {
        	constructor(public firstName: string, public lastName: string) {}
      }
      c = new Person('matt', 'smith')

      🤎 선택형 프로퍼티

      	let a: {
         		b: number
         		c?: string
       }
       
       a = {b: 1}
      	b = {b: 1, c: undefined}
      	c = {b: 1, c: 'd'}
       
       	// 예시
          let airplaneSeatingAssignments: {
            [seatNumber: string]: string
          } = {
            '34D': 'Boris Cherny',
            '34E': 'Bill Gates'
          }

      🤎 인덱스 시그니처
      : 이 객체에서 모든 T 타입의 키는 U 타입의 값을 가짐

      	[key: T]: U
       
       	// 예시
          let airplaneSeatingAssignments: {
            [seatNumber: string]: string
          } = {
            '34D': 'Boris Cherny',
            '34E': 'Bill Gates'
          }

      🤎 읽기 전용 프로퍼티
      : 이 객체에서 모든 T 타입의 키는 U 타입의 값을 가짐

      let user: {
        	readonly firstName: string
      } = {
        	firstName: 'abby'
      }
      
      user.firstName						// string
      user.firstName = 'abbey with an e'  	// Error: 'firstName'은 읽기 전용 프로퍼티이므로 할당할 수 없음
    • 배열

       let a = [1, 2, 3]				// number[]
        var b = ['a', 'b']			// string[]
        let c: string[] = ['a']		// string[]
        let d = [1, 'a']				//  (string | number)[]
        const e = [2, 'b']			// (string | number)[]
      
        let g = []					// any[]
        g.push(1)						// number[]
        g.push('red')					// (string | number)[]
      
        function buildArray() {
         	let a = []					// any[]
          a.push(1)					// number[]
          a.push('x')					// (string | number)[]
          return a
        }
        let myArray = buildArray()	// (string | number)[]
    • 튜플
      : 배열의 서브타입
      : 길이가 고정됨, 각 인덱스의 타입이 알려진 배열의 일종
      : 서언할 때 타입을 명시해야함

       let a: [number] = [1]
        let b: [string, string, number] = ['kang', 'kim', 1988]
        
        // 선택형 요소
        let trainFares: [number, number?][] = [
          [3.75],
          [8.25, 7.70],
          [10.50]
        ]
        // 위와 같음
        let moreTrainFares: ([number] | [number, number])[] = [
          ...
        ]
          
       // 최소 길이 지정: 나머지 요소(...)
       // 최소 한 개의 요소를 갖는 string 배열
       let friends: [string, ...string[]] = ['Sara', 'Tali', 'Chloe', 'Claire']
      
       // 이형 배열
       let list: [number, boolean, ...string[]] = [1, false, 'a', 'b', 'c']
      • 읽기 전용 배열과 튜플
        : 읽기 전용 배열을 갱신하려면 .push, .splice처럼 내용을 바꾸는 동작 대신 .concat, .slice 같이 내용을 바꾸지 않는 메서드를 사용해야 함

        let as: readonly number[] = [1, 2, 3]			// readonly number[]
         let bs: readonly number[] = as.concat(4)		// readonly number[]
         let three = bs[2]								// number
         as[4] = 5										// Error: 'readonly number[]'의 인덱스 시그니처 타입은 읽기만 허용
         as.push(6)										// 'push' 프로퍼티는 'readonly number[]' 타입에 존재하지 않음
         
        type A = readonly string[]						// readonly string[]
        type B = ReadonlyArray<string>					// readonly string[]
        type C = Readonly<string[]>						// readonly string[]
        
        type D = readonly [number, string]				// readonly [number, string]
        type E = Readonly<[number, string]>				// readonly [number, string]
    • null, undefined, void, never

      • null
        : 값이 없음
        => 값을 계산하려 하면 에러 발생

      • undefined
        : 아직 정의하지 않았음

      • void
        : 명시적으로 아무것도 반환하지 않는 함수의 반환 타입
        ex) console.log

      • never
        : 절대 반환하지 않는 함수 타입
        ex) 예외를 던지거나 영원히 실행되는 함수
           function a() {
             throw TypeError('I always error')
           }
      
           function b() {
             while(true) {
               doSomething()
             }
           }

      💙 unknown이 모든 타입의 상위 타입이라면 never는 모든 타입의 서브타입

    • 열거형
      : 해당 타입으로 사용할 수 있는 값을 열거하는 기법
      : 키를 값에 할당하는, 순서가 없는 구조
      : 각 멤버에 명시적으로 값을 할당하는 습관을 기르는 것이 좋음

      enum Language {
      	English,
      	Spanish,
      	Russian
      }
      
      let myFirstLanguage = Language.Russian			// Language
      let mySecondLanguage = Language['English']		// Language
      
      // 타입스크립트가 자동으로 열거형의 각 멤버에 적절한 숫자를 추론해 할당하지만,
      // 값을 명시적으로도 설정 가능
      enum Language {
      	English = 0,
      	Spanish = 4,
      	Russian						// 타입스크립트가 4 다음 숫자인 5로 추론
      }
      
      // 열거형에 문자열 값을 사용하거나 문자열과 숫자 값을 혼합 가능
      enum Color { 
          Red = '#c10000',
          Blue = '#009ac1',
          Pink = 0xc10050,			// 16진수 리터럴
          White = 255					// 10진수 리터럴
      }
      
      let a = Color.red				// Color
      let b = Color.Green				// Error: 'Green' 프로퍼티는 'typeof Color' 타입에 존재하지 않음
      let c = Color[255]				// string
      let d = Color[6]				// string   !!! 접근할 수 없어야 하지만 타입스크립트는 접근을 허용함!!!
      
      // const enum: 문자열 리터럴로만 접근가능
      // 위와 같은 안전하지 않은 작업을 막을 수 있음
      const enum Language {
      	English,
       	Spanish,
       	Russian
      }
      
      let a = Language.English 		// Language
      let b = Language.Tagalog		// Error: 'Tagalog' 프로퍼티는 'typeof Language' 타입에 존재하지 않음
      let c = Language[0]				// Error: const enum 멤버는 문자열 리터럴로만 접근할 수 있음
      let d = Language[6]				// Error: const enum 멤버는 문자열 리터럴로만 접근할 수 있음

      💙 숫자값을 받는 열거형은 전체 열거형의 안전성을 해칠 수 있음
      💙 열거형을 안전하게 사용하는 방법은 까다로우므로 열거형 자체를 멀리 할 것을 권함


  • 타입 별칭
    : 타입을 가리킴
    : 블록 영역에 적용
    type Age = number
    type Person = {
    	name: string
        age: Age
    }

    let age: Age = 55
    let driver: Person = {
        name: 'James May',
        age: age
    }
  • 유니온 타입
    : 합집합(|)
    type Cat = {name: string, purrs: boolean}
    type Dog = {name: string, barks: boolean, wags: boolean}
    type CatOrDogOrBoth = Cat | Dog
	
	let a: CatOrDogOrBoth = {
    	// Cat, Dog 타입의 프로퍼티를 모두 가질 수 있음
    }
  • 인터섹션 타입
    : 교집합(&)
type Cat = {name: string, purrs: boolean}
type Dog = {name: string, barks: boolean, wags: boolean}
type CatAndDog = Cat & Dog = {
	// name 프로퍼티만을 가질 수 있음
}
profile
프론트엔드 개발자

0개의 댓글