TypeScript (3/3)

thisisyjin·2023년 10월 22일
0

TIL 📝

목록 보기
93/113

TypeScript (3/3)

10-(15) Utility Type

  1. Partial (Partial<Type>)
  2. Pick (Pick<Type, Prop1 | Prop2>)
  3. Omit (Omit<Type, Prop>)

Partial

  • 파셔 타입.
  • 특정 타입의 부분 집합을 만족하는 타입
interface Address {
  email: string;
  address: string;
}

const me: Address  = {}; // Error
const you: Address = {email: "abc@def.com"};  // Error

const me: Partial<Address> = {};  // ✅ OK
const you: Partial<Address> = {email: "abc@def.com"};  // ✅ OK
  • Partial<> 과 같이 적어주면, <> 안에 들어간 타입에 포함된 것이 들어있으면 OK
  • 위 예시에서 me 같은 경우, 빈 객체이지만 Address에 포함되는 것이므로 OK

Pick

  • 몇 개의 속성만 Pick해서 새롭게 타입을 선언
interface Todo {
  title: string;
  desc: string;
  completed: boolean;
}

const todo: Todo = {
  title: "Clean Room",
  completed: true
} // Error

const todo: Partial<Todo> = {
  title: "Clean Room",
  completed: true
} // ✅ OK

type TodoPreview = Pick<Todo, "title" | "completed">; // title, completed 만 골라서 사용

const todo: TodoPreview = {
  title: "Clean Room",
  completed: true
}  // ✅ OK

Omit

  • 몇 개의 속성만 Omit (생략)해서 새롭게 타입을 선언

(위의 예시 이어서 진행)

type TodoPreview = Omit<Todo, "desc">; // desc만 제거

const todo: TodoPreview = {
  title: "Clean Room",
  completed: true
}  // ✅ OK
  1. Exclude (Exclude<UnionType, Type1 | Type2>)
  2. Required (Required<Type>)
  3. Record (Record<Keys, Type>)

Exclude

  • Union 유형(|로 결합된 타입)을 전달한 다음, 두 번째 인수에서 제거할 멤버 지정
  • `Exclude<UnionType, Type1 | Type2>

Required

  • 일부 속성을 선택 사항으로 정의(? 포함)한 경우에도 객체에 Required 속성이 있는지 체크해야 하는 경우 사용
type User = {
  firstName: string,
  lastName?: string  // optional - 없어도 Not Error
}

const user: Required<User> = {
  firstName: "Tom"
}  // Error 

Record

  • 속성키가 Keys이고 타입이 Type인 타입을 생성
interface CatInfo {
  age: number;
  breed: string;
}

type CatName = "miffy" | "boris" | "bordred"

const cats:Record<CatName, CatInfo> = {
  miffy: {age: 9, breed: "ab"},
  boris: {age: 3, breed: "cd"},
  bordred: {age: 5, breed: "ef"}
}

ReturnType

  • 함수의 반환 타입으로 구성된 타입을 생성
type T0 = ReturnType<() => string> // string
type T1 = ReturnType<(s: string) => void> // void

10-(16) Implememts vs Extends

Implements

  • 새로운 클래스의 타입 체크를 위해서 사용되며, 그 클래스의 모양을 정의할 때 사용
  • 부모 클래스의 프로퍼티 or 메서드를 상속받아 사용하는 것은 X

class Ford implements Car {}

  • Car에는 있는 메서드가 Ford 클래스에는 없는 것을 체크 가능
  • class가 아닌 interface로도 가능
interface Part {}

class Ford implements Car, Part {} // Car클래스의 속성과 Part 인터페이스의 속성 모두 가지고 있어야 함 

Extends

  • 부모 클래스에 있는 프로퍼티나 메소드를 상속해서 사용하는 것

🤔 Extends vs Implements

  • Extends는 직접 상속해서 사용 가능한 것
  • Implements는 부모와 같은지 체크하는 것

10-(17) Keyof operator

keyof 연산자

  • 제공된 타입의 키(Key)를 추출하여 새로운 Union 유형으로 반환하는 것
interface IUser {
  name: string;
  age: number;
  address: string;
}

type UserKeys = keyof IUser; // "name" | "age" | "address"
  • 객체를 타입으로 변환한 후, keyof로 키만 유니언으로 변환 가능
const user = {
  name: "John",
  age: 20,
  address: "Seoul"
}

type UserKeys = keyof typeof user; // "name" | "age" | "address"
  • enum(객체와 유사) -> 마찬가지로 keyof typeof 하면 키만 유니언으로 변환 가능

10-(18) Mapped Types

  • 중복을 피하기 위하여 다른 타입을 바탕으로 새로운 타입 생성 가능
  • type이 다른 type에서 파생되고, 동기화 상태를 유지해야 하는 경우에 유용함
type AppConfig = {
  name: string;
  email: string;
};

type AppPremissions = {
  changeName: boolean;
  changeEmail: boolean;
};
  • 위 예제에서 두 타입 사이 암시적 관계가 있기 때문에 문제가 있음.
  • 두 타입에 대한 적절한 업데이트를 동시에 수행하기 위해서는 Mapped Type을 이용하는 것 권장.

맵스 타입

  • 예> Array.prototype.map()
let arr = [1, 2, 3];
let StringArr = arr.map(value => value.toString()); // ['1', '2', '3']
  • TypeScript에서 맵스 타입이란, 하나의 타입을 가져와 각 속성에 변환을 적용하여 다른 타입으로 전환한다는 의미이다.

예제 1

type Users = 'Kim' | 'Lee' | 'Park';

type UserFirstNames = {[K in USers]: string}; // 하나씩 가져오고 string으로 전환
type UserAges = {[K in Users]: number}; // 하나씩 가져오고 number로 전환

위 타입은 아래와 같다.

type UserFirstNames = {
  "Kim": string,
  "Lee": string,
  "Park": string
}

type UserAges = {
  "Kim": number,
  "Lee": number,
  "Park": number
}

예제 2

이 부분 이해 잘 안됨.

type DeviceFormatter<T> = {
  [K in keyof T]: T(k);
}

type Device = {
  manufact: string;
  price: number;
  fixed: boolean;
}

const phone: DeviceFormatter<Device> = {manufact: 'abc', price: 100, fixed: true};
// keyof로 인해 Device의 키들을 추출하여 Union으로 변환함 
// Device<"manufact" | "price" | "fixed"> 가 됨

10-(19) tsconfig.json

전체 구성

  1. compilerOptions: 컴파일러 옵션
  2. files: 컴파일할 개별 파일 목록 + 확장자명
  3. include: 변환할 폴더 경로를 지정
  4. exclude: 변환하지 않을 폴더 경로를 지정
  5. extends: 상속해서 사용할 다른 TS config파일 지정

compilerOptions

  1. lib
{
  "lib": ["ESNext", "DOM"], // 사용할 라이브러리
}
  • 사용할 라이브러리 정의
  • 작성하지 않아도, 기본 값으로 사용되는 라이브러리들도 존재함 (target에 따라)
  1. moduleResolution
  • 컴파일러가 모듈을 찾는 방법

  • Relative, Non-Relative 인지 구분

    • Relative: "../../module"
    • Non-Relative: "module" (baseURL 기준으로 해석)
  • Classic, Node 전략 중 하를 이용하여 모듈을 찾을 위치를 알려줌

  • 현재 기본 값은 Node 전략 (Relative 또는 Non-Relative)

  1. baseUrl
  • Non-Relative 모듈 해석 과정에 하나의 과정 추가됨
  • 예> "baseUrl": "./" 사용 시, tsconfig 파일과 동일 경로에서 시작하는 파일을 찾음
  1. paths
  • import { bar } from '../../../../bar' 와 같이 경로가 길어지는 경우 단축키처럼 사용 가능
// tsconfig
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@src/*": [
        "scr/*"
      ]
    }
  }
}
// ts
import { bar } from '@src/bar'
  1. isolatedModules
  • 해당 옵션을 true로 설정 시, 모든 각각의 소스코드 파일을 모듈로 강제로 만들기 가능
  • 해당 파일에서 import, export 사용 시 그 파일은 모듈이 되지만, 그렇지 않으면 전역 공간으로 정의되고 모듈이 아니기에 에러가 발생
  1. removeComments
  • 컴파일 시 모든 주석을 제거해주는 옵션
  1. allowJs
  • js -> ts -> js 로 변환 시 필요
  • 자바스크립트와 타입스크립트를 함계 사용
  1. checkJs
  • allowJs와 함께 작동
  • checkJs 활성화 시, JS 파일의 오류가 보고됨 (JS 파일 맨 위에 // @ts-check 사용하는 것과 동일
  • 즉, 런타임에야 에러가 발생하는 JS 파일을 TS처럼 에러를 미리 체크해볼 수 있는 옵션임!
  1. forceConsistentCasingInFileNames
  • 파일 이름을 대소문자 판별하게 하는 옵션
  • true값을 주면 대소문자를 정확히 판별해야함
  1. Declaration
  • true값을 주면 TS -> JS 컴파일 과정에서 선언 파일을 생성함 (d.ts)
  • 이 선언 파일에서 타입들만 따로 관리 가능함
  1. strict
  • 더 엄격하게 타입 체크
  • any 타입 에러 (noImplicitAny)
  • 엄격한 null 검사 (strictNullChecks)
  • 엄격한 함수 유형 검사 (strictFunctionTypes) 등이 모두 true로 변경됨
profile
기억은 한계가 있지만, 기록은 한계가 없다.

0개의 댓글