gpt4 book ai didi

typescript - typescript 中的传播运算符不保证正确的类型

转载 作者:行者123 更新时间:2023-12-03 21:10:18 25 4
gpt4 key购买 nike

我正在使用扩展运算符创建具有更改字段的副本,如下例所示 (run)。但是如果在创建对象字面量时更改了字段的类型,编译器不会提示:

class A{
constructor(readonly a: number, readonly b: string[]){}
copy(): A { // must return an object of type A
return {
...this,
b: 99 // should be of type string[]!
}
}
}

const a: A = new A(1, ["x", "y"])
const a1 = a.copy()
console.log(JSON.stringify(a1))
输出:
[LOG]: "{"a":1,"b":99}"
创建显式接口(interface)也无济于事:
interface IA {
readonly a: number
readonly b: string[]
}

...

copy(): IA { ...
看起来它与数组无关,因为下一个示例也会编译:
class A{
constructor(readonly a: number, readonly b: number){}
copy(): A {
return {
...this,
b: "my string" // should be of type number!
}
}
}
为什么这在 TypeScript 中是可能的?或者它是一个编译器错误?有没有办法避免

最佳答案

这是以下类型系统事实之间的交互:

  • this真的是多态的this类型。多态this是扩展当前类的类的隐式泛型类型参数。 (reference 见最后一段)
  • 如果展开操作涉及泛型类型的操作数,则结果是展开的项目类型的交集。 reference
  • 一个交集可以分配给它的任何成分。例如类型 A & B可分配给 AB无论 A 的任何属性之间是否存在任何不兼容和 B ( example ) ( reference 参见分配兼容性)

  • 在这里应用这 3 个规则,我们得到 { ...this, b: 99 } 的类型如 this & { b: number } ( proof)。可分配给 A自从 this extends A .
    例如,如果您键入 assert thisA ,你实际上会得到一个错误,因为不涉及通用操作数的扩展操作输入正确( ex)
    至于这是否是一个错误,我将其称为设计限制。很长一段时间以来,使用带有泛型类型操作数的扩展是不可能的。此功能是在 3.2 ( PR) 中添加的,阅读 PR 中的注释我们可以清楚地看到团队意识到了这里的一些漏洞:

    An alternative to using intersections would be to introduce a higher-order type operator { ...T, ...U } along the lines of what #10727 explores. While this appears attractive at first, it would take a substantial amount of work to implement this new type constructor and endow it with all the capabilities we already implement for intersection types, and it would produce little or no gain in precision for most scenarios. In particular, the differences really only matter when spread expressions involve objects with overlapping property names that have different types. Furthermore, for an unconstrained type parameter T, the type { ...T, ...T } wouldn't actually be assignable to T, which, while technically correct, would be pedantically annoying.


    添加了上面的重点,您的用例属于这个确切的问题。

    关于typescript - typescript 中的传播运算符不保证正确的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64359757/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com