我有一个函数,它接受一个对象

declare function f<T extends object>(body: T): any;

f({
  type: "object",
})

函数签名如下所示:

function f<{
    type: string;
}>(body: {
    type: string;
}): any

但我预计会是:

function f<{
    type: "object";
}>(body: {
    type: "object";
}): any

而不在传递对象时实际用作常量.

有没有办法可以将对象类型显式推断为只读?

推荐答案

您可以使用const type parameter来表示对类似const-assertion的推理的偏好:

declare function f<const T extends object>(body: T): any;

f({ type: "object" })
/* function f<{ readonly type: "object"; }>(
    body: { readonly type: "object"; }
): any */

这里,对象文字{ type: "object" }的类型已被推断为{ readonly type: "object" },而不需要显式as const.

因此,type属性是both readonly and a字符串literal type.

这个问题似乎没有区分readonly属性和原义属性,所以我想这在这里并不重要.但请注意,一般来说,readonly个属性不需要是文本类型,文本类型的属性也不需要是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

Playground link to code

Typescript相关问答推荐

带有联合参数的静态大小数组

无法正确推断嵌套泛型?

使用动态主体初始化变量

类型脚本返回的类型包含无意义的泛型类型名称

如何调整对象 struct 复杂的脚本函数的泛型类型?

我可以以这样一种方式键入对象,只允许它的键作为它的值吗?

是否可以基于对象的S属性值[]约束对象的其他属性值用于类型化的对象数组?

使用订阅时更新AG网格中的行

`fetcher.load`是否等同于Get Submit?

如何在方法中正确地传递来自TypeScrip对象的字段子集?

为什么我的导航在使用Typescript的React Native中不起作用?

tailwind css未被应用-react

是否可以通过映射类型将函数参数约束为预定义类型?

声明遵循映射类型的接口

如何键入对象转换器

类型';只读<;部分<;字符串|记录<;字符串、字符串|未定义&>';上不存在TS 2339错误属性.属性&q;x&q;不存在字符串

在tabel管理区域react js上设置特定顺序

Svelte+EsBuild+Deno-未捕获类型错误:无法读取未定义的属性(读取';$$';)

为什么 typescript 在对象合并期间无法判断无效键?

如何将参数传递给条件函数类型