Open3

TypeScriptのユニオン型を手で書かないでTypeカタログを使おう

Katsushi OUGIKatsushi OUGI

元ネタ: https://x.com/GabrielVergnaud/status/1893345211117367537

type Text = {type: 'text'; content: string;}
type Image = {type: 'image'; src: string;}
type Video = {type: 'video'; src: string;}

// こうじゃない
export type Post = Text | Image | Video;

// Typeカタログを利用せよ
export type PostCatalog = {
    text: Text;
    image: Image;
    video: Video;
}

// 全型のユニオン型
export type PostType = keyof PostCatalog;

// 上記のPostと同じ
export type Post = PostCatalog[PostType];

メリット1

カタログがあることで、importのタイプ数が減る

import {PostCatalog} from "~posts"
const image: PostCatalog['image'] = {
//
type: 'image',
src: '/images/cat.jpg'
}
Katsushi OUGIKatsushi OUGI

メリット2

サブユニオン型が簡単につくれる。

import {PostCatalog} from "~/posts"

type WithSRC = PostCatalog['image' | 'video']

nameのユニオンから型のユニオン型をgetできる。

Katsushi OUGIKatsushi OUGI

メリット3

ジェネリックを書くのが楽ちん。 ExtractExclude が不要。

const DEFAULT_POSTS: PostCatalog = {...}

function getDefaultPost<T extends PostType>(
  type: T
): PostCatalog[T] {
  return DEFAULT_POSTS[type]
}