やりたいこと
const a: EmptyObject = {} //OK
const b: EmptyObject = {hoge: "aaa"} //NG
const c: EmptyObject = "hoge" //NG
となるようなEmptyObject型を作成したい。
結論
type EmptyObject = {[key: string]: never}
NG例
type EmptyObject = {}
これだと
const a: EmptyObject = {} //OK
const b: EmptyObject = {hoge: "aaa"} //OK
const c: EmptyObject = "hoge" //OK
になってしまいます。
理由としては、{}
は特殊な型で、nullとundefined以外を許容してしまうからです。
補足:{}
の型について
{}
がnullとundefined以外を許容してしまうのは、JavaScriptはプリミティブに対してもプロパティアクセスができることが関係しています。
例えば、string型には.lengthというプロパティがあるので、
type StringObject = {
length: number;
}
const hoge: StringObject = "a"
ということができます。number型も同様に
type NumberObject = {
toString(): void;
}
const hoge: NumberObject = 1
ということができます。つまり、{}だけではstringの可能性もnumberの可能性も捨てきれないことになり、許容しているということになります。