0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

君は "A" | "B" のUnion型から "AA" | "BB" 型を作れるか

Posted at

Claudeくんが頭いい型定義を教えてくれたので共有。

↓のような型定義があるとき、

type AB = "A" | "B";

↓のような型を定義したい。どうするか。

"AA" | "BB"

真っ先に思いつくのは↓の形。

type AABB = `${AB}${AB}`;

しかし、これは実際には "A""B" の組み合わせになってしまう↓。

スクリーンショット 2025-01-27 20.21.13.png

ではどうするかというと、↓のようにすればよい。

type Hoge<T extends string> = T extends any ? `${T}${T}` : never;
type AABB = Hoge<AB>;

スクリーンショット 2025-01-27 20.25.56.png

ポイントは↓。

  • T extends any が必ず true になる
  • ↑の T"A" or "B" のいずれかが選ばれた状態で、 ${T}${T} により2連続で並ぶことが表現できる

以上、TypeScriptは奥が深いね〜って話でした。

余談

この話の使い所はAIお絵かき用の自作ツール。

"red" | "blue" | "green" のような色を定義したUnion型と、
別途指定した文字列型を組み合わせて、

  • "red hair ribbon -> red ribbon"
  • "blue hair ribbon -> blue ribbon"
  • "green hair ribbon -> green ribbon"

のような文字列を型として定義したい。
そんなときにClaudeくんがこの記事のノウハウを教えてくれた。

実際のコードは↓のようなもの。

export type ColorPalette = "default" | "unchi";

export const COLOR_PALETTE = {
  default: [
    "aqua",
    "black",
    "blue",
    "brown",
    "green",
    "grey",
    "orange",
    "pink",
    "purple",
    "red",
    "white",
    "yellow",
  ],
  unchi: ["💩"],
} as const satisfies Record<ColorPalette, readonly string[]>;

type Color<T extends ColorPalette> = (typeof COLOR_PALETTE)[T][number];

type AliasableColorTag<
  T extends Color<ColorPalette>,
  U extends string,
  V extends string,
> = T extends any ? `${T} ${U} -> ${T} ${V}` : never;

export const generateColorAliasableTagTable = <
  T extends string,
  U extends string,
  V extends ColorPalette,
  W extends object,
>(
  fromTag: T,
  toTag: U,
  colorPalette: V,
  obj: W,
) => {
  type C = Color<V>;

  const entries = COLOR_PALETTE[colorPalette].map((color: C) => {
    return [
      `${color} ${fromTag} -> ${color} ${toTag}` as AliasableColorTag<C, T, U>,
      { ...obj, to: `${color} ${toTag}` },
    ] as const;
  });

  return ObjectModule.fromEntries(entries); // これはTSの型推論が💩だから作った自作のオブジェクト操作用モジュール
};
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?