Kuzunoha-NEのブログ

プログラミングなどの勉強をしてます

【TypeScript】ifとimport

こんばんは、葛の葉です。

さて、TypeScriptで条件によってモジュールをインポートする、あるいはインポートしないようにしたい場合があるかと思います。

if(true){
    import {hoge, moge} from "./ex";
}

// error TS1232:  An import declaration can only be used in a namespace or module.

An import declaration can only be used in a namespace or module.とエラーを出されます。VSCodeでもエラーが出力されます。

f:id:Kuzunoha-NE:20191114203155j:plain
An import declaration can only be used in a namespace or module.

書いてあるとおり、名前空間かモジュール内じゃないとimport出来ないようです。

動的なimport

TypeScriptにおいては、プログラムを実行しつつモジュールをimportするにはimport()として関数を使用します。

developer.mozilla.org

import関数はPromiseが返却されますので、以下のように使うことが出来ます。なお、ex.tsは以下のようになっています。

// ex.ts
export const hoge:string = 'hogehoge';
export const moge:string = 'mogemoge';
// 呼び出すtypescript
if(true){
    import("./ex").then((value)=>{
        console.log(value);
    });
}
// { hoge: 'hogehoge', moge: 'mogemoge' }

もちろんasync await も使用可能です。

(async () => {
    if(true){
        const hogehoge = await import("./ex");
        console.log(hogehoge);
    }
})();
// { hoge: 'hogehoge', moge: 'mogemoge' }

が、残念ながらスコープ的にifの外から出ることはできません。

(async () => {
    if(true){
        const hogehoge = await import("./ex");
        console.log(hogehoge);
    }
    console.log(hogehoge);
})();
// error TS2304: Cannot find name 'hogehoge'.
// 
// 6     console.log(hogehoge);

webpackなどでインポートするだけなら以下のように記述することも出来ます。VSCode上では赤波線が出てきて警告を受けますが、問題なく使えます。

(async () => {
    if(true){
        await import("./ex.css");
    }
})();