質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.40%
ESLint

ESLintは、JavaScriptのための構文チェックツール。全検証ルールを自由に on/offでき、独自のプロジェクトに合わせたカスタムルールを容易に設定することが可能。公開されている様々なプラグインを組み込んで使用することもできます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

2回答

237閲覧

as const なオブジェクトリテラルのプロパティ名でユニオン型を定義するには?

zohnam

総合スコア1442

ESLint

ESLintは、JavaScriptのための構文チェックツール。全検証ルールを自由に on/offでき、独自のプロジェクトに合わせたカスタムルールを容易に設定することが可能。公開されている様々なプラグインを組み込んで使用することもできます。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2024/06/24 02:25

実現したいこと

ユニオン型を、 0 | 1 | 2のようにマジックナンバー指定するのではなく、
オブジェクトリテラルでのプロパティ名で指定したいです。

const DataType = { A_1: 0, A_2: 1, A_3: 2, B_1: 3, B_2: 4, C_1: 5, C_2: 6, C_3: 7, } as const type DataTypeA = DataType.A_1 | DataType.A_2 | DataType.A_3 type DataTypeB = DataType.B_1 | DataType.B_2 type DataTypeC = DataType.C_1 | DataType.C_2 | DataType.C_3

as const で変更不可能な静的データ保証をしているから、DataTypeA は 0 | 1 | 2 相当として解釈してくれるのを期待したのですが、

Cannot find namespace 'DataType'

とネームスペースとして解釈されて、

type DataType.A_1 = /*unresolved*/ any

となってしまいます。

typeof とか keyofとかを駆使すればなんとかなりそうな気がするんですが、どうすればいいのでしょうか?

前提

enumで定義しろ、という回答は申し訳ありませんが、意味がありません。

最終目標は、「enum(またはそれに準ずるもの)として型定義されたものは、マジックナンバー(number値)との比較を禁止(または検出)できないだろうか?」です。

enumで定義すれば上記のようなエラーはでませんが、マジックナンバー比較禁止はできなさそうでした。
今はオブジェクトリテラルではできないだろうか、という調査中なのです。

なお、eslintのno-magic-numbersは、目的外のあらゆる箇所でのマジックナンバー使用を指摘されて、意図に沿いませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

一案を挙げておきます。
A, B, C それぞれの値の配列を作っておくと何かと便利だったりするので、
所与の const DataType に対して

typescript

1const valuesA = [DataType.A_1, DataType.A_2, DataType.A_3] as const 2const valuesB = [DataType.B_1, DataType.B_2] as const 3const valuesC = [DataType.C_1, DataType.C_2, DataType.C_3] as const

という3つの配列を作っておいて、

typescript

1type DataTypeA = typeof valuesA[number] // 0 | 1 | 2 2type DataTypeB = typeof valuesB[number] // 3 | 4 3type DataTypeC = typeof valuesC[number] // 5 | 6 | 7

とします。

投稿2024/06/24 12:16

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zohnam

2024/06/24 22:38

配列があると、どこかでループ処理で活用できますもんね メモらせていただきます
guest

0

ベストアンサー

変数名はそのままでは型として使えません。typeofを入れてください。

typescript

1const DataTypeValues = { 2 A_1: 0, 3 A_2: 1, 4 A_3: 2, 5 B_1: 3, 6 B_2: 4, 7 C_1: 5, 8 C_2: 6, 9 C_3: 7, 10} as const 11 12// 以下のどちらか 13type DataType = typeof DataTypeValues 14type DataTypeA = DataType['A_1'] | DataType['A_2'] | DataType['A_3'] 15 16type DataTypeB = typeof DataTypeValues.B_1 | typeof DataTypeValues.B_2 17

投稿2024/06/24 05:42

maisumakun

総合スコア145628

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zohnam

2024/06/24 22:35

typeofで行けそう…という予感までしてたのに、なんでこんなシンプルなことに自分は気付けなかったのか… 助かりました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.40%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問