質問: Block<"hasNumber" | "hasBoolean">[];` のような指定では目的の仕様は達成できませんでした。 よろしくお願いします。
回答: `Block`と`BlockList`を次のように書き換えれば目的の仕様になります。 ``` type SingleTypeBlock = { id: string; type: T; attribute: Attribute; } type GetBlock = T extends BlockType ? SingleTypeBlock : never; type Block = GetBlock; type BlockList = Block[]; ``` 質問者さんがお書きになった`Block`型は`SingleTypeBlock`と改名しました。 実は、今回欲しいのは`SingleTypeBlock<"hasNumber"> | SingleTypeBlock<"hasBoolean">`というユニオン型です。この定義にすれば、`list`の3つ目のようなちぐはぐな値を弾くことができます。 しかし、手動で`SingleTypeBlock<"hasNumber"> | SingleTypeBlock<"hasBoolean">`と書くのは`BlockType`があとから増えた際に大変ですから、`BlockType`が増えれば自動的にユニオン型の構成要素が増えるようにしたいです。 それを担うのが`GetBlock`です。これはconditional typeのunion distributionという挙動を利用して、`BlockType`の構成要素の各`T`に対して`SingleTypeBlock`を計算し、それらのユニオン型をとるようになっています。 よって、`GetBlock`が`SingleTypeBlock<"hasNumber"> | SingleTypeBlock<"hasBoolean">`に計算されます。