在使用带有默认参数的泛型类型时,如果变量是用泛型类型声明的,我就会失go 推理的好处.

假设有以下类型:

type Attributes = Record<string, any>;

type Model<TAttributes extends Attributes = Attributes> = {
  attributes: TAttributes;
};

function create<TModels extends Record<string, Model>>(
  schemas: TModels
): TModels {
  return schemas;
}

如果我使用Model来输入对象,然后将该对象传递给我的泛型函数,那么如果我使用not来输入该对象,我将失go 获得的推理益处.如果将泛型参数传递到Model类型,则它会按预期工作.如下所示:

const TodoWithGeneric: Model<{ name: string; finished: string }> = {
  attributes: {
    name: "string",
    finished: "boolean"
  }
};

const TodoWithoutGeneric: Model = {
  attributes: {
    name: "string",
    finished: "boolean"
  }
};

const withInference = create({
  Todo: { attributes: { name: "string", finished: "boolean" } }
});
const withGenericsPassed = create({ Todo: TodoWithGeneric });
const withoutAttributesPassedToGeneric = create({
  Todo: TodoWithoutGeneric
});

有没有一种类型脚本解决方案,可以仍然具有类型化对象声明的好处,without必须传递泛型参数,但在传递到函数后仍然保留不类型化/推理的好处?

理想情况下,我们应该在TodoWithoutGeneric的声明上有打字脚本支持,但是当它传递到withoutAttributesPassedToGeneric时,我们go 掉了Model类型,并允许推理接管.

此问题中的组合代码片段设置在此沙箱中: Code Sandbox here

withInference.Todo.attributes.withGenericsPassed.Todo.attributes.具有可用的属性键,而withoutAttributesPassedToGeneric.Todo.attributes(使用泛型键入)则没有.

谢谢!

推荐答案

一旦你用一个像Model这样的(非union)类型的变量annotate

const TodoWithoutGeneric: Model = ⋯;

那么这就是编译器所知道的关于变量类型的全部信息.它已经被一路扩大到Model个.有关初始值设定项的任何特定信息都已丢弃.因此,如果您需要保留更具体的信息,则不能这样注释该类型.

假设您只想确保TodoWithoutGeneric satisfiesModel类型,而不实际将其扩大到该类型.如果是这样,您可以使用the satisfies operator:

const TodoWithoutGeneric = {
    attributes: {
        name: "string",
        finished: "boolean"
    }
} satisfies Model;

如果初始值设定项不符合Model,仍然会出现错误,但现在TodoWithoutGeneric的类型更具体

/* const TodoWithoutGeneric: {
    attributes: {
        name: string;
        finished: string;
    };
} */

并且您的代码的其余部分将按预期运行.

Playground link to code

Typescript相关问答推荐

如何在排版中正确键入中间件链和控制器链

使Typescribe强制所有对象具有相同的 struct ,从两个选项

contextPaneTitleText类型的参数不能分配给remoteconfig类型的关键参数'""'''

有没有办法解决相互影响的路由之间的合并?

使用泛型keyof索引类型以在if-condition内类型推断

Next.js错误:不变:页面未生成

如何使用WebStorm调试NextJS的TypeScrip服务器端代码?

了解类型规则中的关键字

如何在Type脚本中动态扩展函数的参数类型?

CDK从可选的Lambda角色属性承担角色/复合主体中没有非空断言

复选框Angular 在Ngfor中的其他块中重复

->;Boolean类型的键不能分配给类型Never

如何连接属性名称和值?

从类型脚本中元组的尾部获取第n个类型

如何在Reaction Native中关注屏幕时正确更新状态变量?

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

如何提取具有索引签名的类型中定义的键

是否使用类型将方法动态添加到类?

如何使用动态生成的键和值定义对象的形状?

使用嵌套属性和动态执行时,Typescript 给出交集而不是并集