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