똑같은 삽질은 2번 하지 말자

Typescript + Vue 본문

Vue

Typescript + Vue

곽빵 2021. 10. 10. 18:23

Typescript 로 마이그레이션 하면서 기록하고 싶은것들

1. 결과값(JSON)이 비었을 경우 해당 결과를 빈 배열로 초기화 하고 싶을때

JSON.parse에서는 param이 String

 

2. debugger  중단점 말고 키워드로 디버깅하는 방법 (꽤 유용할꺼 같아 적어놓음)

 

3. computed 의 반환타입은 무조건 넣어줘야 올바른 추론이 이루어질 수 있다.

computed의 사용용도?

  • 간결하고 직관적인 템플릿 표현식
  • 조건에 따라 HTML 클래스를 추가/변경할 때
  • Vuex의 state값에 접근할 때
  • 다국어 라이브러리에도 활용 가능 

4. 자동 추론.. 타입을 정의해야하는 필요성에 대해 좀더 깊게 생각해보자

밑의 경우는 fetch의 리턴타입을 정의함으로써 sort안 내부 메소드의 param의 자동추론이 이루어지는 케이스인데,

sort 메소드의 param은 타입정의가 필요없어지는게 포인트!

 

5. (vue-cli)를 이용한 $ vue add typescript 는 안하는게 좋다.. 자동으로 파일내용을 변경해버리는게 많기 때문에

이건 몰랐던 기능!! 검색타겟을 replace하는것
이것도 몰랐던 기능.. vscode내부에서 파일검색대상제외

 

6. Type Alias와 Interface의 차이점

Type Alias(타입 별칭)와 Interface를 보면 거의 똑같은 기능을 하고 있는것 처럼 보이는데,

그런데 큰 차이가 하나 있다. Interface는 선언 병합이 가능하지만, Type Alias는 그렇지 않다는것.

 

Interface의 선언 병합(extends)

Interface는 동일한 이름으로 여러 번 선언해도 컴파일 시점에 아래처럼 합칠 수 있습니다.

이런 동작을 선언 병합(Declaration Merging)이라 한다. (vue의 인터페이스에 vuex가 선언병합을 이용해 Store타입을 넣고있다.)

// vue/type/vue
export interface Vue {
  readonly $el: Element;
  readonly $options: ComponentOptions<Vue>;
  readonly $parent: Vue;
  readonly $root: Vue;
  readonly $children: Vue[];
  readonly $refs: { [key: string]: Vue | Element | (Vue | Element)[] | undefined };
  readonly $slots: { [key: string]: VNode[] | undefined };
  readonly $scopedSlots: { [key: string]: NormalizedScopedSlot | undefined };
  readonly $isServer: boolean;
  readonly $data: Record<string, any>;
  readonly $props: Record<string, any>;
  readonly $ssrContext: any;
  ...이하 생략
}

// vuex/type/vue
declare module "vue/types/vue" {
  interface Vue {
    $store: Store<any>;
  }
}

https://yamoo9.gitbook.io/typescript/interface/extends

 

인터페이스 확장 - TypeScript Guidebook

클래스 방식이 아닌 객체 리터럴 방식으로 객체를 사용하고자 할 경우, 객체를 할당 받을 변수에 인터페이스를 설정할 수 있습니다. 이 때 인터페이스에 정의된 준수 사항을 따르지 않을 경우,

yamoo9.gitbook.io

 

TypeScript 팀의 의도

TypeScript 팀은 개방-폐쇄 원칙(OCP, Open-Closed Principle) (소프트웨어 개체(클래스, 모듈, 함수 등등)는 확장에 대해 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다'는 프로그래밍 원칙)에 따라 확장에 열려있는 JavaScript 객체의 동작 방식과 비슷하게 연결하도록 Interface를 설계했다.

그래서 TypeScript 팀은 가능한 Type Alias보단 Interface를 사용하고, 합 타입 혹은 튜플 타입을 반드시 써야 되는 상황이면 Type Alias를 사용하도록 권장하고 있습니다.

 

음.. 타입 별칭은 인터섹션(&)을 이용해서 확장 비스무레한 것(?)을 할 수 있기때문에 어느쪽을 쓰든 솔직히 상관없다는 느낌이 아직까지는 강하다... 물론 타입팀의 의도처럼 인터페이스를 기본베이스로 가져가는게 좋을듯하다.. 와 닿지는 않지만 일단 그러려니하고 넘어가자.

 

 

declare module에 대해서(ts, js 컴파일내용도 들어있다.)

 

[TypeScript] module, import, export, declare 개념 정리

👉 모듈(Module)이란? import 또는 export 가 있는 파일은 모듈(Module)로 취급이 된다. 즉, 외부에서는 직접적으로 모듈을 불러오지 않는 이상 그 모듈의 데이터를 사용할 수 없다. import 는 모듈에서 데

it-eldorado.tistory.com

내부모듈(namespace)과 외부모듈

 

TypeScript #6 모듈(Modules)

오늘은 타입스크립트 모듈(modules)에 대해 공부했던 내용을 정리해 보려고 한다. 모듈 모듈은 독립 가능한 기능의 단위이다. 여러 모듈을 결합하면 하나의 프로그램을 만들 수 있는데, 모듈을 사

devowen.com

 

7. Store의 타입 추론이 안되는 이유

위의 사진처럼 나는 state안에 여러가지의 배열들을 선언 빈값으로 초기화까지 해주었지만

밑의 사진처럼 state에 뭐가 있는건지 전혀 추론이 안되고있다.

추론이 안되고있다..

밑의 스샷은 node_modules안의 vuex의 타입인데 vuex의 라이브러리 타입구조상 default로 any형이 들어가고 있기때문에 따로 Generic을 넘겨주지 않는이상 추론이 이루어질 수 없는 구조이다. ㅠ

any가 들어가 있기때문에 타입추론이 안되었던것
node_modules/vuex/types/vue.d.ts

위의 any 부분을 건들면 모든 컴포넌트에서 타입추론이 잘 이루어지더라.. 물론 실무에서 활용할 수 있는 방법은 아니지만,

이런것도 있다하고 넘기면 될 것 같다.

 

8. ref 속성 타입 정의 방법

<template>
  <div>
    <div ref="my"></div>
  </div>
</template>

<script lang="ts">
import Vue, { VueConstructor } from "vue";

export default (Vue as VueConstructor<Vue & { $refs: { my: HTMLDivElement } }>).extend({
  mounted() {
    this.$refs.my; // HTMLDivElement
  }
});
</script>

refs의 기본적인 타입

타입 인터섹션을 이용해서 my: HTMLDivElement가 $refs 타입안에 확장되어 추론되게끔 한다.

 

이러한 부분들도 Vue3이되면 좀더 쉽게 타입을 씌울 수 있게 해주었을꺼같은 느낌이드는데 나중에 한번 찾아보자.

 

9. Event타입 커스텀하기

export namespace VueEvent {
  export interface Input<T extends EventTarget> extends InputEvent {
    target: T;
  }
}


Event -> target 속성이 정의되어 있다 그래서 제네릭으로 target속성의 타입을 재정의 하려고 하면 에러가 나기때문에 EventTarget을                   상속받아서 해야한다.
   ↓         
UIEvent
   ↓
InputEvent
   ↓
VueEvent

InputEvent는 타겟의 타입이 HtmlInputElement와 매치가 안됨
EventTarget을 상속받으며 타입을 확장시킴으로써 호환 ok 제네릭타입으로도 확장 가능
value속성에 바로 접근가능하다

 

Comments