Is there a more efficient way to specify the type of a property in TypeScript without resorting to casting? Take a look at this example:
interface Overlay {
type: "modal" | "drawer"
other?: number
}
const rec = {
obj1: { type: "modal" },
obj2: { type: "drawer" },
...
}
The object rec
currently has the type
{ obj1: { type: string }, obj2: { type: string } }
. The desired type is { obj1: Overlay, obj2: Overlay, ... }
.
I have attempted different methods:
- Option 1 - effective but verbose and creates additional variables
const obj1: Overlay = { type: "modal" }
const obj2: Overlay = { type: "drawer" }
const ...
const rec = { obj1, obj2, ... }
- Option 2 - prone to hiding errors (e.g.
{} as Overlay
is accepted by TS). Usingsatisfies
only validates on a per-property basis.
const rec = {
obj1: { type: "modal" } as Overlay,
obj2: { type: "drawer" } as Overlay,
...
}
- Option 3 - loses key type information (
replaces with"obj1" | "obj2" | ...
string
)
const rec: Record<string, Overlay> = {
obj1: { type: "modal" },
obj2: { type: "drawer" },
...
}
- Option 4 - overlooks details about the 'other' property and improperly sets the type of 'type' to either
"modal"
or"drawer"
instead of the union type
const rec = {
obj1: { type: "modal" },
obj2: { type: "drawer" },
...
} as const
Are there better alternatives than #1 to achieve the correct type?