ウェブサイト検索

typescript - DOM を未定義の可能性があるとして宣言する方法


私の同僚と私は現在、モノレポ内でNuxtを使用して新しいVue SSRアプリを構築しています。Nuxtアプリはパッケージとしてあり、もう一つは私たちのコンポーネントライブラリです。私たちは皆TypeScriptにはあまり慣れていませんが、問題なくすべてをセットアップすることができました。

問題は、コンポーネントライブラリはSSRに対応している必要がありますが、Nuxt自体を意識するべきではないということです。そのため、windowのプロパティにアクセスする際には、if (process.browser)よりもif (typeof window !== 'undefined')を使いたいです。今、考えているのは、誰かがwindowのプロパティにアクセスする際に、まずそれが定義されているかどうかを確認せずにアクセスしようとした場合に、TypescriptとEslintを使ってエラーを出せるかどうかです。

// Not SSR friendly
const halfWinHeight = window.innerHeight / 2

// SSR friendly
if (typeof window !== 'undefined') {
  const halfWinHeight = window.innerHeight / 2
}

私は、ユニオン型を使うと、Typescript が次のようなエラーを出すことを知っています:

declare const window: {} | undefined

すると、私は Object はおそらく 'undefined' です というエラーがほしいです

もちろん、すべての可能な window や document のプロパティを宣言したいわけではありません。なので、DOM のようなライブラリを使えないかと思っていますが、その DOM は場合によっては未定義かもしれません。厄介なのは、window が定義されているかどうかが実行時にしかわからないという点です。では、TypeScript にビルド時に値を認識させるためには、どうやって値を代入すればよいのでしょうか?

私はこれをTypeScriptで解決しようとしていますが、最善の方法ではないかもしれません。どんな助けでも大変ありがたいです。

回答 #1

一つの可能な解決策:

  1. dom ライブラリを使用して、window の型宣言を取得します:

    // tsconfig.json
    {
      "compilerOptions": {
        "lib": ["dom"]
      }
    }
    
  2. windowをtypeof window | undefinedとして型付けしてエクスポートするユーティリティファイルを作成します:

    // @/utils/window.ts
    export default window as typeof window | undefined
    
  3. すべてのファイルで window(dom から)を使用する場合は、ユーティリティファイルを window としてインポートし、カスタム型バージョンが使用されるようにします:

    // MyFoo.vue
    import window from '@/utils/window'
    
    export default {
      mounted() {
        window.console.log('hi')  // ❌ Object is possibly 'undefined'
        ^^^^^^
    
        window?.console.log('hi') // ✅
      }
    }