【问题标题】:TypeScript allowing incorrect properties via object destructuringTypeScript 通过对象解构允许不正确的属性
【发布时间】:2021-11-26 02:20:17
【问题描述】:

我遇到了 TypeScript 的问题,即使用一种类型的对象可以通过破坏性赋值注入到使用完全不同类型的另一个对象中,而 TypeScript 不会显示任何错误。

一个例子是:

interface Pizza {
    cookingTime: number;
    size: "Small" | "Medium" | "Large";
}

interface Car {
    modelName: string;
    yearManufactured: number;
}

const produceMalformedPizza = (car: Car): Pizza => {
    return {
        ...car, // This is not a "Pizza" object but no errors are raised
        cookingTime: 10,
        size: "Small",
    }
}

console.log(
    produceMalformedPizza({
        modelName: "NotAPizza",
        yearManufactured: 1980
    })
)

/* Output:
[LOG]: {
  "modelName": "NotAPizza",
  "yearManufactured": 1980,
  "cookingTime": 10,
  "size": "Small"
} 
*/

我已尝试打开所有可能的严格标志 — 你可以看到它正在编译 online here

如果我尝试在 produceMalformedPizza 函数中返回任何特定属性,那么编译器会如预期的那样引发错误 — 但似乎我可以使用解构(扩展)赋值注入任意对象数据。

我对 TypeScript 比较陌生,所以也许这是预期的行为? IE。我不能使用具有推断类型安全性的对象传播解构?

编辑:

根据@T.J.Crowder 的回答,这是故意的。

【问题讨论】:

标签: typescript


【解决方案1】:

这是预期的行为。您要返回的对象是Pizza子类型——它具有Pizza 需要的所有属性(加上一些它不需要的属性)。

TypeScript 确实会进行“过多的属性检查”,但仅限于有限的情况。例如,如果您要在该对象字面量中显式放置一个非Pizza 属性,TypeScript 会标记它不是因为从类型角度来看它实际上是错误的(使用子类型很好),而是因为它可能是 一个程序员的错误。

我有点惊讶它不会对 ...car 执行此操作(因为 car 具有必需的属性),但它不会在所有情况下都进行过多的属性检查。

【讨论】:

  • 看起来解构 ...car 不被视为文字对象,因此 excess property checks 不适用。 AFAIK,这是安全的行为
  • @captain-yossarian - 是的,但对我来说,将相同的“实用”多余属性检查应用于作为显式属性的扩展属性是有意义的。但在实施/运行时方面可能成本太高。
  • 我认为这是因为 js 对象的可变性质。好消息,最后你不能使用...car :)
  • @captain-yossarian - 恐怕我不明白。 car 有一个明确的类型,具有不属于Pizza 的必需属性,因此在文字中包含...car 与在其中包含someNonPizzaProperty: "x" 没有根本区别。 (不确定你最后对...car 的意思,return { cookingTime: 10, size: "Small", ...car } 也不会引发任何标志。)
  • 对不起,我最后告诉你使用car,我错了,它不会触发错误。我的例子完全改变了,这就是为什么我得到一个错误
猜你喜欢
  • 2021-02-07
  • 1970-01-01
  • 2020-02-08
  • 2022-06-12
  • 2020-08-10
  • 1970-01-01
  • 2019-08-03
  • 1970-01-01
相关资源
最近更新 更多