Typescript 确实将对象类型定义中不存在的属性分配给对象

Typescript does assign to an object properties that do not exist in the object type definition

提问人:kach haja 提问时间:9/29/2022 更新时间:9/30/2022 访问量:597

问:

我不明白为什么 Typescript 没有将其突出显示为错误......

当我有条件地向对象添加该对象类型定义中不存在的新属性时,Typescript 会分配它

  type Filters = {
      keywords: Array<string>
    }
    
    const condition = 1;
    
    let filters: Filters = {keywords: ['keyword']}
    
    filters = {
      ...filters,
        ...(condition && {...{ tags: ['tag']}}),
      }

结果:

filters: {
  keywords:["keyword"]
  tags:["tag"]
}

虽然我预计会出现此错误:

Object literal may only specify known properties, and 'tags' does not exist in type 'Filters'.

PS:当我尝试以这种方式添加相同的属性时,我收到预期的错误:

filters = {...filters, tags: ['tag']}
JavaScript 打字稿

评论

0赞 katniss 9/29/2022
这回答了你的问题吗?有趣的行为:对象文本可能只指定已知属性
0赞 kach haja 9/29/2022
@caTS在该线程的示例中,它与我的例子相同。答案是>>一旦它被复制到人身上,只有名称属性继续存在<<但实际上,对象被复制到人身上,财产年龄仍然存在,可以随时使用。🤔
0赞 jcalz 9/29/2022
我会说这是 TypeScript 缺少的功能,正如 microsoft/TypeScript#39998 中所要求的那样,多余的属性警告只发生在对象文字中,并且只发生在某些上下文中,并且没有人实现对传播内联对象文字的检查。如果这完全解决了你的问题,我可以写出一个答案;否则,我错过了什么?(请在回复中提及@jcalz,以便通知我)
0赞 kach haja 9/29/2022
@jcalz是的,因为没有人实现对传播内联对象文字的检查。这将完全回答我的问题......谢谢!

答:

1赞 jcalz 9/30/2022 #1

这是 TypeScript 目前缺少的功能;多余的属性检查只发生在特定的上下文中,到目前为止,还没有人对分布到外部对象中的内联对象的内容实现上下文检查。

microsoft/TypeScript#39998 上有一个开放的功能请求。它目前被标记为“正在等待更多反馈”,因此您可能想转到该问题,给它一个 👍 ,并在评论中描述您的用例以及它引人注目的原因。我怀疑采取这样的行动会产生多大影响,但不会有什么坏处。


据我所知,没有一个很好的解决方法可以为您提供这种行为。如果您想使用帮助程序函数,例如

const noExcess = <T extends object>() =>
  <U extends { [K in keyof U]: K extends keyof T ? T[K] : never }>(u: U) => u;

并专门用于:Filters

const noExcessFilters = noExcess<Filters>();

然后调用它:

const z = noExcessFilters({
  ...filters,
  ...(condition && { tags: ['tag'] }),
}); // error!   Types of property 'tags' are incompatible.

它会标记这样的情况,但我不知道这对你来说是否值得。

Playground 代码链接