TypeScript 5.2 で追加された using を利用して、開始・終了のログを出力する

2025-01-26T13:18:00+09:00 | 1分で読めます | 更新日時 2025-01-26T13:18:00+09:00

@

TypeScript 5.2 で追加された using を利用して、開始・終了のログを出力する方法のメモです。

結論

type Logger = {
    log: (message: string) => void;
    [Symbol.dispose]: () => void;
}

const getLogger = (processName: string): Logger => {
    console.log(`start: ${processName}`);
    return {
        log: (message) => {
            console.log(message)
        },
        [Symbol.dispose]: (...args) => {
            console.log(`end: ${processName}`);
        }
    }
}

// Example
function process(input: string) {
    using logger = getLogger('process');
    
    if (input === '') {
        logger.log('input is empty');
        return;
    }

    logger.log('do process');
}

process('hoge');
// start: process 
// do process 
// end: process 
process('');
// start: process 
// input is empty 
// end: process 

解説

using は本来はリソースの解放を忘れずに行うための構文ですが、基本的には try..finally の糖衣構文のはずなので、こういう使い方をすることもできます。
少なくとも TypeScript では try..catch..finally に変換されることを確認できます。気になれば Playground で試してみてください。

console.log の場所を置き換えれば時間計測などにも使えると思います。(おまけに載せてます)

メリット

メリットとしては以下のような点が挙げられます。

  • 早期リターンなどで関数が途中で終了した場合でも、必ず終了のログが出力される
    • 同様のことを他の方法でやるとなると、try .. finally や高階関数などが必要になるため面倒
  • 1行だけでログ出力を行えるので、計測などでサッと入れたい場合に便利

おまけ (時間計測Ver)

const getTimer = (processName: string) => {
    const start = performance.now()
    console.log(`start: ${processName}`);
    return {
        [Symbol.dispose]: () => {
            const end = performance.now();
            console.log(`end: ${processName}: ${(end - start).toFixed(4)}ms`);
        }
    }
}

function process() {
    using _ = getTimer('process');

    for (let i = 0; i < 1000000000; i++) {
      Math.sqrt(i);
    }
}
process();
// start: process
// end: process: 330.6357ms

© 2024 - 2025 nabekou29 Blog

🌱 Powered by Hugo with theme Dream.

About Me

ソフトウェアエンジニア4年目。 主にフロントエンドの開発をしてます。

プロフィールのアイコンは昔に北海道で飲んだコーヒーです。