0605

LOGS

  • typescript のエラーハンドリング

    • Either 型や Result 型は非常に強力なパターン
      • 関数の成功結果と失敗結果を明確に型で表現し、より安全で堅牢なコードを書くのに役立つらしい
    • 従来のエラーハンドリングでは、以下のような方法
      1. nullundefined を返す
        • 成功時はそもそもの値を返す
        • ただ,この2つは呼び出し側がしっかりチェックしないと,null なのか undefined なのかわかりにくい
      2. 例外をスローする throw new Error(...)
        • 関数のシグネチャを見ただけでは例外をスローする可能性がわからない
        • try-catch での処理を忘れるとプログラムがクラッシュする可能性がある
        • どの関数がどの例外を投げるか把握しにくい
    • これらの問題を解決するために「エラーも正常な値の一種として返す」というアプローチを取る
    • Result 型(Result<T, E>

      • 操作が成功した場合には Ok<T> 型の値を,失敗した場合には Err<E> 型の値を保持
      • T は成功時の値の型,E は失敗時のエラー情報の型
      • Result 型の定義例
      // 成功時の値をラップする型
      type Ok<T> = {
        readonly _tag: 'Ok';
        readonly value: T;
      };
      
      // エラー情報をラップする型
      type Err<E> = {
        readonly _tag: 'Err';
        readonly error: E;
      };
      
      // Result型本体
      type Result<T, E> = Ok<T> | Err<E>;
      
      // ヘルパー関数 (Result型の値を簡単に作成するため)
      const ok = <T, E = never>(value: T): Result<T, E> => ({ _tag: 'Ok', value });
      const err = <E, T = never>(error: E): Result<T, E> => ({ _tag: 'Err', error });
      
      // 型ガード (Result型がOkかErrかを判別するため)
      const isOk = <T, E>(result: Result<T, E>): result is Ok<T> => result._tag === 'Ok';
      const isErr = <T, E>(result: Result<T, E>): result is Err<E> => result._tag === 'Err';
      
      • 使用例(文字列を数値にパースする関数)
      function parseNumberResult(input: string): Result<number, string> {
        const num = Number(input);
        if (isNaN(num)) {
          return err(`'${input}' is not a valid number.`); // Err<string> を返す
        }
        return ok(num); // Ok<number> を返す
      }
      
      // 使用例
      const result1 = parseNumberResult("123");
      if (isOk(result1)) {
        // ここでは result1 は Ok<number> 型として扱える
        console.log(`Success (Result): Value is ${result1.value}, Doubled: ${result1.value * 2}`);
      } else {
        // ここでは result1 は Err<string> 型として扱える
        console.error(`Error (Result): ${result1.error}`);
      }
      
      const result2 = parseNumberResult("abc");
      if (isOk(result2)) {
        console.log(`Success (Result): Value is ${result2.value}`);
      } else {
        console.error(`Error (Result): ${result2.error}`);
      }
      // 出力例:
      // Success (Result): Value is 123, Doubled: 246
      // Error (Result): 'abc' is not a valid number.
      
      • is ってなんだ(以前も調べたし,おそらく開発日誌にも書いたことある気がする

        • 型推論を補強する user-defined type guard(ユーザー定義型ガード) に使うらしい
        • unknown, any, Union 型を絞れる
        • const isString = (test: unknown): boolean => {
            return typeof test === "string";
          };
          
          const example = (foo: unknown) => {
            if (isString(foo)) {
              console.log(foo.length); // Error fooはまだunknownとして推論される
            }
          };
          
          • こんな感じ 実際の型エラー
          • これをこうする
          - const isString = (test: unknown): boolean => {
          + const isString = (test: unknown): test is string => {
              return typeof test === "string";
            };
          
          • type predicate というらしい
            • ただし, return typeof test === "number"; にしても,型エラーは出ないが,実行時エラーになる
            • 有名な問題っぽい
            • ライブラリで対策した事例 もある
    • Either 型(Either<L, R>

      • 2つの可能性のうちどちらか一方の値を保持する
      • 慣習的に Left<L>(左側)をエラーや失敗ケースに, Right<R>(右側)を正常系や成功ケースに使う
      • Either 型の定義例 ```ts // Left型 (慣習的にエラー用) type Left = { readonly _tag: 'Left'; readonly left: L; };

      // Right型 (慣習的に成功用) type Right = { readonly _tag: 'Right'; readonly right: R; };

      // Either型本体 type Either = Left | Right;

      // ヘルパー関数 const left = (value: L): Either => ({ _tag: 'Left', left: value }); const right = (value: R): Either => ({ _tag: 'Right', right: value });

      // 型ガード const isLeft = (either: Either): either is Left => either._tag === 'Left'; const isRight = (either: Either): either is Right => either._tag === 'Right'; ``` -

    • Branded Type

      • その前に,判別可能な Union 型(Discriminated Union)

        • 以下サンプルコード

          type Success = {
            type: 'success';
            data: string;
          };
          
          type Failure = {
            type: 'failure';
            error: string;
          };
          
          type Result = Success | Failure;
          
          function handleResult(result: Result) {
            switch (result.type) {
              case 'success':
                // resultはSuccess型に絞り込まれる
                console.log('Data:', result.data);
                break;
              case 'failure':
                // resultはFailure型に絞り込まれる
                console.error('Error:', result.error);
                break;
            }
          }
          
        • 共通フィールドがあるときに使えるやつ
      • 公称型(Nominal Typing) いいなぁ.Golang はこれだったのか
        • TypeScript は構造的部分型なので
        • 柔軟性は確かに高いが,公称型がしたいときもある
        • → やっと登場 Branded Type
      • サンプルコード
      type Brand<T, B> = T & { __brand: B };
      
      type UserId = Brand<string, 'UserId'>;
      type Email = Brand<string, 'Email'>;
      
      // 使ってみる
      const sendEmail = (email: Email) => {
        console.log("Sending email to:", email);
      };
      
      const userId = "user123" as UserId;
      const email = "user@example.com" as Email;
      
      sendEmail(email); // OK
      sendEmail(userId); // type error!
      // Argument of type 'UserId' is not assignable to parameter of type 'Email'.
      
      // 通常のstringも受け付けない
      const plainString = "plain@example.com";
      sendEmail(plainString); // type error!
      // Argument of type 'string' is not assignable to parameter of type 'Email'.
      
  • AIとAWS まわり

    • 生成AIアプリやモデルのバックエンドシステムへのアクセスは 最小権限の原則 に従い,モデルの動作に必要な最小レベルのアクセスのみに制限
    • 特権的な操作を実行する場合にはユーザの承認など 人による判断を入れる(Human in the loop)
      • もちろん限界はある
    • 外部コンテンツをユーザープロンプトから分離
    • 生成AIアプリやモデルを信頼されないユーザーとして扱い,外部ソース,拡張可能な機能(プラグインやダウンストリーム機能など)間の信頼境界を確立する
      • ダウンストリーム機能
        • 主にIT業界やネットワークの文脈で使われる言葉で、サーバーや中心側からクライアントや末端側へ向かうデータや信号の流れ、またはその速度、方向を指します。具体的には、Webサーバーからブラウザへデータを送る際など、下り方向の通信を指します。 by Gemini -

results matching ""

    No results matching ""