I have a function which takes in an object
declare function f<T extends object>(body: T): any;
f({
type: "object",
})
Function signature looks like this:
function f<{
type: string;
}>(body: {
type: string;
}): any
But i expect it to be:
function f<{
type: "object";
}>(body: {
type: "object";
}): any
without actually using as const when passing the object.
Is there any way I can infer the object type explicitly as readonly?
You can use a const
type parameter to indicate a preference for const
-assertion-like inference:
declare function f<const T extends object>(body: T): any;
f({ type: "object" })
/* function f<{ readonly type: "object"; }>(
body: { readonly type: "object"; }
): any */
Here the type of the object literal { type: "object" }
has been inferred as { readonly type: "object" }
, without needing an explicit as const
.
Thus the type
property is both readonly
and a string literal type.
The question as asked doesn't seem to distinguish between readonly
and literal properties, so I guess it doesn't matter much here. But note that in general readonly
properties don't need to be of literal types and literal typed properties don't need to be readonly
:
const readonlyNotLiteral: { readonly a: string } = { a: "abc" };
readonlyNotLiteral.a = "def"; // error
readonlyNotLiteral.a = "abc"; // error
const literalNotReadonly: { a: "abc" } = { a: "abc" };
literalNotReadonly.a = "def"; // error
literalNotReadonly.a = "abc"; // okay