Open4

より詳しくフレンドリーなTypeScriptの型エラーを出したい

sushichan044sushichan044

たとえば、こういう関数を考える。 (もちろん概念的なものだ)

const addTodo = async (name: string) => {
  return await registerTodoInternally(name);
  //                     ^ 実はこの関数に大文字を含む文字列を渡すとエラーになる
}
sushichan044sushichan044

こういう場合、一般的にはバリデーションライブラリを挟んで
registerTodoInternally() に不正な値が入る前にエラーで早期終了させると思う。
もちろん自分もこれは最低限すべきだと思う。

だが、それとは別にコンパイル時点でユーザーフレンドリーなエラーを出せるとより良いとも思う。
(特に、ユーザー入力ではなく開発者が直接コードを呼び出すケースにおいて)

sushichan044sushichan044

やってみた。 TS Playground

declare function registerTodoInternally(name: string): Promise<boolean>;

type ErrorIfNotLowercase<
  T extends string,
  PARAM extends string = ""
> = T extends Lowercase<T>
  ? T
  : `TypeError: Parameter ”${PARAM}” expected a lowercase string`;

const addTodo = async <T extends string = "">(
  name: ErrorIfNotLowercase<T, "name">
) => {
  // some validation here

  return await registerTodoInternally(name);
};

const hoge = await addTodo("task1");
const huga = await addTodo("Task2");
//     ^?

export {}

sushichan044sushichan044

感想: 得られる効果に対して労力が微妙な気がしなくもない。
とはいえ、コンパイラレベルで取りうるデータの領域により厳しい制約を課していくのは
安全なコードを記述する上で役立つと感じる。