🖐️

SvelteとLint、型周り、その他諸々のTips

2023/08/15に公開

SvelteでLintを頑張ったらGenericsを書いた時に怒られが発生したので上手いことやるTips

ESLintの設定はこちらです。
https://github.com/shamokit/svelte-eslint-ignore-setting-generics/blob/main/.eslintrc.cjs

rulesの部分がポイントです。

  • svelte/experimental-require-slot-types
  • svelte/experimental-require-strict-events

この2点は、SvelteにRFCとしてすでに実装されている
strictEvents$$Slotを必須にするeslint-plugin-svelteの設定です。
どちらも仕様がまだ決まっていないので注意してください。
変更されるかもしれません。


strictEventsはdispatchの型を縛れます。
縛っておかないと、とちくるったイベントを親に送ってしまうかもしれないので基本つけておいた方がいいでしょう。


$$Slotは簡単にいうと、slotを受け取るコンポーネントがslotで差し込まれた要素に対して変数を渡す際の型を縛るための型です。(わかりにくいですね)

今回の場合はデフォルトslotにfavoriteFrameworkという名前でstring型のデータを渡しています。
https://github.com/shamokit/svelte-eslint-ignore-setting-generics/blob/main/src/lib/conponent.svelte#L6-L10

こうすると、ここで定義した変数名と型以外は渡せなくなります。

https://github.com/shamokit/svelte-eslint-ignore-setting-generics/blob/main/src/lib/conponent.svelte#L22

<slot favoriteFramework="Svelte" foo="bar" />

みたいにするとfooの部分で怒ってくれます。

https://github.com/shamokit/svelte-eslint-ignore-setting-generics/blob/main/src/routes/%2Bpage.svelte#L18-L29

slotを渡す側ではlet:favoriteFrameworkの部分で受け取れます。


こんな感じで型は結構縛れるのですが、interface $$Slotsはどこにも使用されていないのでESLintが怒ってきます。コラ!
同様にSlots|Events|Props|Genericこの辺も怒られます。

ここは怒ってほしくないので黙らせます。
https://github.com/shamokit/svelte-eslint-ignore-setting-generics/blob/main/.eslintrc.cjs#L30-L38
この部分です。

varsIgnorePatternだけ書いておけば多分OKかと思いますが、試行錯誤した結果が残っているのでいらん人は消してください。
アンスコから始まる変数も怒ってほしくないので|^_の部分も書いていますが、この記事の内容とは関係ありません。

これで使ってない扱いになっている部分が怒られなくなります。


次に、
https://github.com/shamokit/svelte-eslint-ignore-setting-generics/blob/main/src/lib/conponent.svelte#L17

この部分です。
ESLintは$$Genericなんてものは知りません。

なので、
https://github.com/shamokit/svelte-eslint-ignore-setting-generics/blob/main/.eslintrc.cjs#L42-L44
これで教えてあげます。

SvelteでGenericsを扱いたい場合は現時点では2パターン書き方があります。
Svelte5でどっちかに絞ってくれたら嬉しいですね。
以下その辺の補足です。

補足

$$Genericについては後少し補足があって、
https://github.com/dummdidumm/rfcs/blob/ts-typedefs-within-svelte-components/text/ts-typing-props-slots-events.md#generics
Discarded alternative となっています。
Svelte5あたりでどれが採用されるのかわからないですが、genericsの方がもしかしたらいいかもしれません。

ただ、generics="T extends boolean"で書いた場合、
'T' is not defined.とESLintに怒られてしまいます。

いちいち黙らせるのも面倒なので、僕は$$Genericの方で書こうと思います。

その他Tips

https://github.com/shamokit/svelte-eslint-ignore-setting-generics/blob/main/src/lib/conponent.svelte#L36-L72

Svelteコンポーネントは、HTMLコメントを書くとコンポーネント名にホバーした時に書いたものが出てきます。
https://svelte.jp/docs/faq#how-do-i-document-my-components
便利ですね〜

Discussion