😊

【TS】enumの値のunion型が欲しい!

2024/07/18に公開2

悩み

enumの値を関数の引数にしつつ、その関数を呼び出す側はenumの値を文字列として直接指定したいときはどうするんだろう?

これじゃダメだった

enum Currency  {
  JPY = '日本円',
  USD = 'ドル',
  EUR = 'ユーロ'
}

const sampleFunc = (val: Currency) => {
  return val
}

sampleFunc(Currency.JPY) // OK
sampleFunc('日本円') // NG

関数の引数に直接Enumの型を指定すると、関数の呼び出し元の引数にenumの値を直接指定するとこのエラー↓になっちゃう

Argument of type '"日本円"' is not assignable to parameter of type 'Currency'.(2345)

解決方法

関数の引数の型をテンプレートリテラル型を用いてunion型にすることでうまくいく!

enum Currency  {
  JPY = '日本円',
  USD = 'ドル',
  EUR = 'ユーロ'
}

// "日本円" | "ドル" | "ユーロ"
type currency = `${Currency}`

const sampleFuncWithUnionArg = (val: `${Currency}`) => {
  return val
}

sampleFuncWithUnionArg(Currency.JPY) // OK
sampleFuncWithUnionArg('日本円') // OK
sampleFuncWithUnionArg('オーストラリアドル') // enumの値に含まれない値はNG

めでたしめでたし😊

参考記事

https://qiita.com/manak1/items/4b03930ebf9f3377dd23#やり方

株式会社モニクル

Discussion

FAMASoonFAMASoon

良記事ありがとうございます。

本筋と関係ないのですが、TSにはenumがありますがJSにはenumはありません。
そのためJSにトランスパイルする際にコードが肥大化する可能性があります。

enumを使った場合
https://www.typescriptlang.org/play/?#code/KYOwrgtgBAwmBO9QGMCeUoG8BQGBSACgJpQC8UA5IKemgNOaBhihQDS5QCqAygCJmWCTDINcMTFgFFWAJR4VAZwyAfhkC3DBWwBfbNgAuqAA7BYCJCDQA1AIYAbMDvIADACSY4iFKiVXVyAPYgAzmqhfjEJqmwABiYAY8ABQAbmYAXFC29npOLgCUZAB8WCxIagggULGmyqr+gcFhBpEO+mgAdIREaQDc2OVBoeHIkdT0FK3YQA

const enumを使うとランタイムで無駄なコードは省かれます
https://www.typescriptlang.org/play/?#code/MYewdgzgLgBApmArgWxgYUQJ0w4BPGGAbwChCApABQE0YBeGAckFPTQGnNAwxUYBoyYBVAMoARek0CTDIGuGbrwCifAEqjGgM4ZAPwyBbhkYkAviRKhIsCAENkABwA2cAGKIwwUQAoAbsYsAuGAAMAJEQzYuHjaXgCU9AB8xLw4UFhgMK4WOnom5la29o4BOPZ4AHRU1KEA3CRpljZ2wI4sHIylJEA

参考までに共有です

ようへいようへい

共有ありがとうございます!
const enumをしてランタイムで無駄なコードは省く方が良さそうですね!✍️