Open4
TypeScriptのユーティリティ
エラーの原因を再帰的にたどりながらスタックを取得する関数。
/**
* causeを含めてエラーのスタックトレースを取得します。
*
* @example
* const throwError1 = () => {
* throw Error('Error 1');
* };
*
* const throwError2 = () => {
* try {
* throwError1();
* } catch (e) {
* throw Error('Error 2', { cause: e });
* }
* };
*
* try {
* throwError2();
* } catch (e) {
* console.log(chainCauseStacks(e));
* // Error: Error 2
* // at throwError2 (<anonymous>:9:10)
* // at <anonymous>:14:2
* // Caused by: Error: Error 1
* // at throwError1 (<anonymous>:2:9)
* // at throwError2 (<anonymous>:7:4)
* // at <anonymous>:14:2
* }
*/
const chainCauseStacks = (error: Error): string => {
let e: unknown = error;
const stacks: string[] = [];
while (e) {
if (e instanceof Error) {
if (typeof e.stack === 'string') {
stacks.push(e.stack);
e = e.cause;
} else {
break;
}
} else {
stacks.push(String(e));
break;
}
}
return stacks.join('\nCaused by: ');
}
@example
に書いているように、cause
を辿ってstack
を取得します。
『エラーをチェインするライブラリと ES2022 Error Cause』に記載されていたFirefoxのエラー表示形式を参考にしています。
cause
はES2022で追加されたErrorの原因を表すプロパティです。
ref. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
Kotlinのスコープ関数のようなものをすべてのオブジェクトに追加します。[1]
declare interface Object {
run<T, R>(this: T, f: (it: T) => R): R;
}
Object.getPrototypeOf({}).run = function <T, R>(this: T, f: (it: T) => R): R {
return f(this);
};
こんな感じでメソッドでない関数をメソッドチェイン風に繋ぐことができます!
/** `n`の絶対値を返す。`n`が`undefined`であるとき`undefined`を返す。 */
const abs = (n: number | undefined): number | undefined => {
return n?.run(it => Math.abs(it));
};
console.log(abs(-1)); // 1
console.log(abs(undefined)); // undefined
gist: https://gist.github.com/moshg/64d72a3541710fb75626e78cd90a5e38
-
スコープ関数を知らない人向けの解説:【Kotlin】let, with, run, apply, alsoの概要と違い、使い分け【スコープ関数解説】
↩︎
null
またはundefined
であることを判定する関数。
nullishという表現はmdnを元にしています。
/**
* 指定された値が `null` または `undefined` であるとき `true` を返す。そうでないとき `false` を返す。
*
* @see https://developer.mozilla.org/ja/docs/Glossary/Nullish
*
* @example
* isNullish(null) // true
* isNullish(undefined) // true
* isNullish('') // false
*
* @example
* const exampleFn = (x: string | null) => {
* if (isNullish(x)) {
* // x: null
* } else {
* // x: string
* }
* };
*/
export const isNullish = (x: unknown): x is null | undefined => {
return x === null || x === undefined;
};