Type of Empty Record in Typescript
In TypeScript’s type system {}
isn’t what you might think, it’s not a type for empty record:
let zz: {};
zz = {}; // COMPILES
zz = 1; // COMPILES
zz = "1"; // COMPILES
zz = true; // COMPILES
zz = { ff: true }; // COMPILES
zz = [11]; // COMPILES
zz = []; // COMPILES
zz = null; // ERROR: Type 'null' is not assignable to type '{}'.(2322) (when strictNullChecks is on)
zz = undefined; // ERROR: Type 'undefined' is not assignable to type '{}'.(2322) (when strictNullChecks is on)
So what to do if you want a type that will only accept empty record?
type RecordEmpty = Record<string, never>;
let kk: RecordEmpty;
kk = {}; // COMPILES
kk = 1; // ERROR: Type 'number' is not assignable to type 'Record<string, never>'.(2322)
kk = "1"; // ERROR: Type 'string' is not assignable to type 'Record<string, never>'.(2322)
kk = true; // ERROR: Type 'boolean' is not assignable to type 'Record<string, never>'.(2322)
kk = { ff: true }; // ERROR: Type 'boolean' is not assignable to type 'never'.(2322)
kk = [11]; // ERROR: Type 'number' is not assignable to type 'never'.(2322)
kk = []; // ERROR: Type 'never[]' is not assignable to type 'RecordEmpty'. Index signature is missing in type 'never[]'.(2322)
kk = null; // ERROR: Type 'null' is not assignable to type 'RecordEmpty'.(2322)
kk = undefined; // ERROR: Type 'undefined' is not assignable to type 'RecordEmpty'.(2322)
Another alternative alternative might be Record<never, never>
but it’s not working as it should:
declare let r0: {};
declare let r1: Omit<{ a: never }, "a">;
declare let r2: Record<never, never>;
declare let r3: RecordEmpty;
if (typeof r0 === "number") {
// r0: number
r0;
}
if (typeof r1 === "number") {
// r1: number
r1;
}
if (typeof r2 === "number") {
// r2: number
r2;
}
if (typeof r3 === "number") {
// r3: never
r3;
}
r0 = 1; // COMPILES
r1 = 1; // COMPILES
r2 = 1; // COMPILES
r3 = 1; // ERROR: Type 'number' is not assignable to type 'Record<string,never>'.(2322)