🧊

SvelteKitのTypeScriptに、実験的なHTML属性を認識させる

つまりは、input要素のwebkitdirectoryのこと・・・。

TypeScript自体ではサポートされてる

TypeScript/src/lib/dom.generated.d.ts at main · microsoft/TypeScript https://github.com/microsoft/TypeScript/blob/b4787652d281188da1d61fe9cc3a17589f20c9fc/src/lib/dom.generated.d.ts#L11080

ので、こういうコードは型エラーにならない。

const $i = document.createElement("input");
$i.webkitdirectory = true; // 🆗

問題はSvelteのテンプレートで<input type="file" webkitdirectory>って書いたとき。

Svelteのテンプレート部は、自家製の型定義

Svelteのテンプレート部で書けるHTMLは、TS本体のそれではなく独自の型が反映されるようになってる。

bind:とか独自のシンタックスとの都合もあるんであろう。

そしてそこに、今回求めてるwebkitdirectoryがないってわけ。

Add support for boolean attribute webkitdirectory · Issue #7872 · sveltejs/svelte https://github.com/sveltejs/svelte/issues/7872

自分で拡張するしかない

というわけで、このSvelteの型定義を自分で拡張する。

この方法自体は、Svelte(Kitではない)のドキュメントにも書いてある。

TypeScript • Docs • Svelte https://svelte.dev/docs/typescript#enhancing-built-in-dom-types

こういう型定義をglobal.d.tsみたいな適当な名前で用意して。

declare module "svelte/elements" {
  export interface HTMLInputAttributes {
    webkitdirectory?: boolean | undefined | null;
  }
}

export {};

SvelteKitなプロジェクトなら、それをsrc配下に置くだけでいい。

もしくは、SvelteKitには似た用途のapp.d.tsが元々あるので、そこに同居させてもよい。

// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
  namespace App {
    // interface Error {}
    // interface Locals {}
    // interface PageData {}
    // interface Platform {}
  }
}

// 🆕
declare module "svelte/elements" {
  export interface HTMLInputAttributes {
    webkitdirectory?: boolean | undefined | null;
  }
}

export {};

なんしか、これで型エラーが解消される!