Nuxt+TypeScriptの事始め #nuxtmeetup / Nuxt and TypeScript
by
Sue
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
Nuxt+TypeScript 事始め #NuxtMeetup @sue71 2018/05/15
Slide 2
Slide 2 text
自己紹介 Masaki Sueda github: sue71 twitter: @sue__71 Merpay web フロントエンド/iOS ソリューションチーム 便利屋 技術課題を解決する人
Slide 3
Slide 3 text
今日話すこと Vue プロジェクトのTypeScript 対応状況や相性 Nuxt+TypeScript の対応方法 Vue Vuex Nuxt
Slide 4
Slide 4 text
TypeScript?
Slide 5
Slide 5 text
TypeScript の特徴 静的型付け言語でJavascript が書ける 型定義による型の後付け
Slide 6
Slide 6 text
TypeScript のメリット Type Safe Less test / documentation
Slide 7
Slide 7 text
Vue プロジェクトの型定義状況 コンポーネント 対応状況 備考 vue ◯ ver 2.5=> で改善 vue-template ✕ 型解析されない vuex △ 型定義はあるが... nuxt ✕ 型定義がない
Slide 8
Slide 8 text
環境構築
Slide 9
Slide 9 text
IDE VSCode Typescript 補完バッチリ Vetor for VSCode Vue 公式プラグイン Language-Service-Protocol 準拠 Vue ファイルの補完
Slide 10
Slide 10 text
Lint eslint-plugin-vue を使いたい -> eslint TypeScript -> typescript-eslint-parser で対応 Interface などがlint に引っかかる場合があるので幾 つかルールをOFF にする no-unused-vars no-undef
Slide 11
Slide 11 text
Vue + TypeScript
Slide 12
Slide 12 text
Vue Component v2.5 からComponentOption 形式に対応 tscon g にてnoImplicitThis をtrue に ⇢ 暗黙的なthis へのマッピングを解決 Vue.extend({ data() { return { hoge: 0 } }, computed: { foo(): string { return this.hoge; // Error } } });
Slide 13
Slide 13 text
Vue Stateless Component template のみのファイルを読み込むためのtweak declare module "*.vue" { import Vue from "vue"; export default Vue }
Slide 14
Slide 14 text
hello.vue
Hello
hello-container.vue import Vue from "vue"; import hello from "hello.vue"; export default Vue.extend({ components: { hello } })
Slide 15
Slide 15 text
Vue-Plugin Vue にインジェクトされるもの型を定義する $store, $router, etc... VueComponentOption に提供されるメソッドの型 を定義する
Slide 16
Slide 16 text
Vuex-Store declare module "vue/types/options" { interface ComponentOptions { store?: Store; } } declare module "vue/types/vue" { interface Vue { $store: Store; } }
Slide 17
Slide 17 text
Vuex + TypeScript
Slide 18
Slide 18 text
Vuex データフローは最も重要な部分 → TypeSafe に書きたい 型定義はあるがany で定義されるものが多い → TypeSafe じゃない
Slide 19
Slide 19 text
型定義ファイル type MutationTree = { [key: string]: ( state: State, payload: any, rootState: RootState ) => void } 実装 const mutations: MutationTree<{}, {}> = { increment(state, payload /*any*/) { } };
Slide 20
Slide 20 text
型定義を改善する TypeScript2.1 から提供されているMappedType を 利用 → キーと引数の型の組み合わせが定義できる
Slide 21
Slide 21 text
追加の型パラメータ type Couter = { increment: number; } 改善した型定義 type MutationTree = { [K keyof Mutations]: ( state: State, payload: Mutations[K] /*Counter[increment]*/, rootState: RootState ) => void }
Slide 22
Slide 22 text
実装 const mutation: MutationTree<{}, {}, Counter> = { increment(state, payload /*number*/) { state.count = payload } }
Slide 23
Slide 23 text
Actions dispatch やcommit の定義もtypesafe にできる const actions: ActionTree<..., CouterA, CounterM> = { increment(context, payload) { context.commit("increment", "hoge"); // Error context.commit("incremento", 1) // Error } }
Slide 24
Slide 24 text
TypeSafe ではあるが、、 実装と一致しないInterface を定義する気持ち悪さ は残る namespaced ではない場合さらに型パラメーターを 渡さなければならない
Slide 25
Slide 25 text
No content
Slide 26
Slide 26 text
Nuxt + Typescript
Slide 27
Slide 27 text
NuxtContext Nuxt から提供されるコンテキストAPI export interface NuxtContext { app: Vue; isClient: boolean; isServer: boolean; isStatic: boolean; // ... beforeNuxtRender: Function; } 参照: https://nuxtjs.org/api/context/
Slide 28
Slide 28 text
nuxtServerInit declare module 'vuex/types/index' { interface ActionTree { nuxtServerInit?: (..., context: NuxtContext) => void; } }
Slide 29
Slide 29 text
Pages /pages 配下のコンポーネントに対して与えられる 拡張 interface PageComponentOptions { layout?: string | (ctx: NuxtContext) => string; ... middleware?: string | string[] }
Slide 30
Slide 30 text
まとめ
Slide 31
Slide 31 text
Vue プロジェクトでTypeScript 採用するなら型定義 書くくらいの気持ちは必要 完全にTypeSafe に書きたいならAngular, React を推 奨 Nuxt みたいに機能の多いAPI を覚えるのは大変 定義があるとAPI にどこで何ができるかすぐ分か るしプロジェクトの皆で共有できる → 取り敢えずTypeScript 使っていきましょう
Slide 32
Slide 32 text
ご清聴ありがとうございました。