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.