# TypeScriptのIndex Signatureでプロパティに制限をかけたかったので、今更ながらよくよく調べてみた

3 min read
Table of Contents

Index Signatureを使用することでプロパティの型を指定することができる。

例えば、

interface BodyType {
[key: number]: {
min: number,
max: number
}
}
const body:BodyType =
{
String: {
min: 0,
max: 230
},
1: {
min:0,
max:300
}
}
console.log(body.String.min)}
]

上記のようにnumber型という風に明示的に宣言することで、Stringという文字列をkeyに指定したことでエラーを吐かせることが可能である。

type '{ hello: { min: number; max: number; }; 1: { min: number; max: number; }; }' is not assignable to type 'BodyType'.
Object literal may only specify known properties, and 'hello' does not exist in type 'BodyType'.

逆にIndex Signatureを文字列という風に明示的に宣言することで、1というKeyがエラーを吐きそうだが、

This is because when indexing with a number, JavaScript will actually convert that to a string before indexing into an object

という風に文字列にしてからアクセスするので問題ないということで、エラーは出ない。

Index Signatureでは特定の文字列を持つプロパティのみを制約することはできない

じゃあ、keyが特定の文字列のみの場合はどうすればいいか?

interface BodyType {
[key in 'a' | 'b']: {
min: number,
max: number
}
}

上記の記述すると、

A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.

というエラーが出る。

エラーが出たコードを実現しようとすると

interface Content {
min: number,
max: number
}
interface BodyType {
a: Content,
b: Content
}

という風に記載することで解決できる。

そもそもIndex Signatureの定義が

Sometimes you don’t know all the names of a type’s properties ahead of time, but you do know the shape of the values.

という風に型のプロパティ名を事前にすべて把握していない場合に使用する物なので、そもそも実現しようとしていることが間違え。

間違えだけれど、ちなみに、Typeを使用することで、上記のような書き方で実現することができる。

type BodyType = {
[key in 'a' | 'b' | 'c']: {
min: number,
max: number
}
}

InterfaceとTypeの違いは別で調べたい。

My avatar

Thanks for reading my blog post! Feel free to check out my other posts or contact me via the social links in the footer.


More Posts

Comments