以下はちゃんと管理されているプロジェクトでは、こんなことはあまり起こらないだろうなという内容です。
僕は Flux の State 部分をこのように定義して使ったりすることが多いです。
interface State {
values: {foo: any; bar: any}[];
}
オブジェクト部分なども直で書いてます。(APIの仕様がはっきりしないままで、どの値を使えばいいのか曖昧なことが多いというのが大きい、今の会社)
そして、例えばそのvalues
のうちの1つ、つまり{foo: any; bar: any}
だけを受け取る関数などを定義したいときに、指定に例えば(value: {foo: any; bar: any}) => void
のようにしても問題はあまりないですが、できれば先程定義したState
から使いたいです。
TypeScript の型は子プロパティ名で絞り込んでいくことができます。つまり、{foo: any; bar: any}[]
はState['values']
とも書くことができます。ただここで「[]
はどうすれば取り払えるんだろう」と頭をひねりました。ただそれはすぐ解決することができました。
配列型 T[] から T だけ取り出して使う
ここでいうT[]
ですが、実は TypeScript では以下のように定義したものとほぼ同じです。
interface StateValues extends Array {
[n: number]: string
}
const state: StateValues = ['foo'];
この[n: number]: string
部分はインデックス署名と言い、extends number
なプロパティ名ならプロパティへのアクセスが許可されるようになります。これは型のプロパティ名での絞り込みでextends number
な型を指定することで、さらに絞ることができるということになります。
つまり、以下のような絞り込み方法があります。(僕的にはnumber
がいいかなと思います)
const value0: State['values'][number] = 'foo';
const value1: State['values'][0] = 'foo';
const value2: State['values'][1] = 'foo';
const value99: State['values'][99] = 'foo';
State['values'][]
{foo: any; bar: any}[][]