I am looking to create a custom object with predefined "base" properties, as well as additional properties. It is important for me to be able to export the type of this new object using the typeof
keyword. I want to avoid having to define an interface for this object because new properties are added to it frequently, and updating both the object and the interface can become cumbersome.
- I want a compile-time error if a property is added to
Base
but not toderived
- I need to export the type of
derived
along with all its properties - No need for a separate type or interface for
derived
export type Base = {
id: string;
}
// elsewhere
export const derived = {
id: "42",
foo: "bar"
}
If I create the object without any specific type information, I won't receive compile-time errors if it doesn't adhere to the structure defined in Base
.
One initial approach would be to simply type derived
as Base
:
export const derived: Base = {
id: "42",
foo: "bar" // error: type { ... } is not assignable to { ... }
}
export type Derived = typeof derived; // The expected type should include { id: string; foo: string }
The compiler will flag an error here because even though I've typed derived
as Base
, I have included properties that are not part of Base
.
An alternative solution is to type derived
as a combination of Base
and additional unknown properties using something like Record<string, unknown>
:
export const derived: Record<string, unknown> & Base = {
id: "42",
foo: "bar"
}
export type Derived = typeof derived; // Now: Record<string, unknown> & { id: string; }
However, when using typeof derived
, the resulting type does not capture the extra properties like foo
, since it interprets them as keys within an arbitrary record.
The only workaround I could think of involves creating an unused variable of type Base
and assigning derived
to it solely for type-checking purposes:
export const derived = {
id: "42",
foo: "bar"
}
export type Derived = typeof derived; // This now provides the correct type
const _: Base = derived; // This will raise an error if derived doesn't adhere to the Base structure
I am wondering if there is a way to type derived
so that it can extend Base
without losing type information when using typeof
. Is such a type definition possible?