Home > Back-end >  Typescript misunderstanding - why are all properties required in a Record?
Typescript misunderstanding - why are all properties required in a Record?

Time:11-12

In this trivial example:

type AllowedKeys = 'a' | 'b'

const someObject: Record<AllowedKeys, boolean> = {a:true, b:false}

const anotherObject:  Record<AllowedKeys, boolean> = {a:true}

someObject is valid but anotherObject is not:

Property 'b' is missing in type '{ a: true; }' but required in type 'Record<AllowedKeys, boolean>'.

Why is this?

CodePudding user response:

Because Record basically spreads out the union into discrete properties, like this:

{
    a: boolean;
    b: boolean;
}

This is shown in the documentation:

interface CatInfo {
  age: number;
  breed: string;
}
 
type CatName = "miffy" | "boris" | "mordred";
 
const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};

If you want a and b to be optional, you can apply Partial:

type AllowedKeys = 'a' | 'b'

const someObject: Partial<Record<AllowedKeys, boolean>> = {a:true, b:false}
//                ^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−^
const anotherObject:  Partial<Record<AllowedKeys, boolean>> = {a:true}
//                    ^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−^

Now, both are valid.

Playground link

  • Related