当前位置: 首页 > 知识库问答 >
问题:

TypeScript具有扩展和默认参数的通用约束

曹子平
2023-03-14

所以我试图写一个函数,它有一个泛型,它扩展了一个特定的对象,从而约束了它。接下来,我想将这个泛型与参数的定义一起使用,以生成一个新的“增强”参数。这一切都很好,但一旦我想引入一个默认值的参数TypeScript抱怨如下消息(这在操场上的一些不同的变化):

功能:

const test1 = <T extends { foo?: string }>(options: T & { bar?: boolean } = {foo: 
''}) => {
    console.log(options);
}

错误:

类型“{foo:string;}”不可分配给类型“T”

编译器警告我,我可能想使用foo,实际上我做到了。是简单地不可能以这种方式使用泛型,还是这是TypeScript中的一个错误?

共有2个答案

微生慈
2023-03-14

这些初始化都不起作用的原因是您无法初始化您不知道的东西。考虑下面的呼叫:

test1<{ foo: string, goo: boolean}>();

泛型参数对函数有效,但它有一个额外的属性,goo,这是强制性的,但在选项的默认值中未指定。这就是编译器抱怨赋值的原因,你不知道T的最终形状,你只知道它的最低要求,所以你不能构建一个与T兼容的对象

如果您同意选项没有在泛型类型参数上指定所有必需属性,则可以使用类型断言

const test1 = <T extends { foo?: string }>(options: T & { bar?: boolean } = <any>{foo: ''}) => {
    console.log(options);
}
柏修洁
2023-03-14

定义时键入T是未知的,因此编译器会抛出此错误,您无法初始化您不知道的内容。我可以想到一些变通方法,但不确定它们对您的案例有多大用处。

您可以保持类型T不变,并对options参数使用联合类型,如下所示:

const test1 = <T> (options: T | { bar?: boolean } | { foo?: string } = { foo: '' }) => {
  console.log(options);
};

另一种解决方法是使用类型断言并手动告诉编译器初始值设定项属于它需要的类型:

const test2 = <T extends { foo?: string }>(options: T & { bar?: boolean } = { foo: '' } as T & { bar?: boolean }) => {
  console.log(options);
};

但请记住,这些只是变通方法,无论何时必须使用变通方法,它都意味着设计中的缺陷。也许你可以重新审视你的逻辑并改进它,以消除对这些变通方法的需求。或者,您可以跳过参数初始化,添加options.foo=options.foo || '';作为函数中的第一行代码。只是一些想法。

 类似资料:
  • 问题内容: 我有这个功能: 如您所见,它将字典转换成一个字典(没有可选的)。 我只想为值是任何类型的类使用新方法扩展该类,但是我无法为字典的通用参数添加约束。 这是我尝试的: 但失败并显示错误: 问题答案: 在Playground中尝试以下代码: 因为您不能在协议扩展的子句中指定确切的类型,所以可以准确检测到该类型的一种方法是使UNIQUELY符合协议(例如)。 为了获得的包装值类型,我在自定义协

  • 我一定错过了一些明显的东西,因为这真的让我大吃一惊。 以下代码给出了错误: 是否有理由必须实例化一个带有1个默认值的参数的模板,并为其指定一个值? 有人能引用标准吗?

  • 问题内容: 在Java中,默认情况下所有类都扩展了任何默认类吗? 示例:如果我有一个简单的课程,例如: 此类默认情况下是否扩展了类? 问题答案: class是所有类的超类。 类对象是类层次结构的根。每个类都有Object作为超类。所有对象(包括数组)都实现此类的方法。 您可以测试一下:

  • 我想在模板类之外定义如下所述的函数。 已经为第二个参数尝试了很多组合,它是一个模板,并且也接受默认参数。 我希望它是在类之外定义的实际得到编译器错误,如果它是简单的类型,我可以很容易地在第二个参数中提到int、浮动等。

  • 问题内容: 我试图弄清楚如何在C扩展模块中具有一个函数的变量(也许有很多)参数。 阅读有关PyArg_ParseTuple的内容,您似乎必须知道要接受多少,一些强制性的和一些可选的,但都具有自己的变量。我希望PyArg_UnpackTuple能够处理此问题,但是当我尝试以似乎错误的方式使用它时,它似乎只会给我总线错误。 举个例子,将以下可能要放入扩展模块中的python代码(用C语言编写)。 这可

  • 我试图理解下面的代码片段 当使用指针类型示例int*调用时,默认参数是如何工作的? 当obj1.test()被调用时,编译器将生成什么。我得到一个编译器错误当我尝试