TypeScript 5.6回归:对于具有所有可选属性的类型的参数类型推断不正确

ffx8fchx  于 9个月前  发布在  TypeScript
关注(0)|答案(9)|浏览(168)

🔎 搜索词

inference, param

🕗 版本与回归信息

  • 在版本5.5.4和5.6.0之间发生了变化

⏯ Playground链接

https://www.typescriptlang.org/play/?ts=5.6.0-dev.20240816#code/JYOwLgpgTgZghgYwgAgMoHsC2EAqBPABxQG8AoZC5AeiuQHkRkBWAOgDYWAGAGmQgA8iUYNnDIARnmSY4Aa1ABzZGAAWwAM7ICUdAWRQIARwCuwAwBMW5SsZDATEAAo6CAfgBcydWGEgFAblIAX1JScwgEABs4A2QEdBBvZHRxdU86VOgANzhxSIgAHgxsfCIAPkDSGFsEMGAE5BiFAHEIMHUAdR0-UogACgBKdMyoHLzC4iCy5DJKfTbjKEYU9RYCYCI+sDgCPqbkAF5p2bnKJsDTyhoAPVdrS5pkAFFBCMhzT2LcQhRQZhZWAAWe6nR4AQVqxjgkU8FEmyD+WVYHE4AFpxG04Mp0P8UajwlkWAAmThEwGcAAcAEY2Mg9mBkPk4N4BiCggMBoEQlUanUGk1Wu0AMLoKAGWq9QYzEEGMCLZapNYbfrbXb7I7Sy4Uc4guY3O5a6i0MGRADucDwmniYrebI5XNCoEgsEQKAy6myuXyBRwxxB6yIBTBZT6unSQjgYFFADFefUQD7eMGhvQRmNvcGHU7oPAkMgAKogGJ4WMgWrxxPIABKxzp6nQiyQnhwKar-mQIWzLrzdAjUagpfLCUrNb4-EgIHMmkLxcHfIT7s94x9ZV4i9GXsKNdrnfAOddyAAsgl0L1e9BIzG48PfWOJ1P6H2r2X55Xb8QO2EItFYtUX-HlB2Fc+hAAQwE8PockiYwIGbAZDmmLJ0GAcwU2PEBTx+c8oEvAdrwTX1AiAA

💻 代码

  1. interface SomeType {
  2. // On 5.6.0, experiment by making this prop required.
  3. uniqueProp?: string;
  4. }
  5. declare const obs: Observable<SomeType>;
  6. function argGetsWrongType(): Observable<{}> {
  7. return obs.pipe(tap(arg => {
  8. arg;
  9. //^?
  10. // Expected: SomeType in 5.5.4
  11. // Actual: {} in v5.6.0-beta to 5.6.0-dev.20240816 (at least)
  12. }));
  13. }
  14. function argGetsCorrectType() {
  15. return obs.pipe(tap(arg => {
  16. arg;
  17. //^?
  18. // Always correct
  19. }));
  20. }
  21. interface Observable<T> {
  22. pipe<A>(op: OperatorFunction<T, A>): Observable<A>;
  23. }
  24. interface UnaryFunction<T, R> { (source: T): R; }
  25. interface OperatorFunction<T, R> extends UnaryFunction<Observable<T>, Observable<R>> { }
  26. interface MonoTypeOperatorFunction<T> extends OperatorFunction<T, T> { }
  27. declare function tap<T>(next: (value: T) => void): MonoTypeOperatorFunction<T>;

🙁 实际行为

arg 被推断为 {}

🙂 预期行为

arg 被推断为 SomeType ,这在v5.5.4中是一致的。

shstlldc

shstlldc1#

Bisects to this diff , so the change likely was introduced by #57909

bqjvbblv

bqjvbblv2#

顺便说一下,在谷歌的代码库中,我看到其他与推理相关的新bug不断出现。就我所知,我无法为一个特定情况创建一个简化的复现示例,我已经观察了一段时间...
我会尽快添加其他复现示例...

yvgpqqbh

yvgpqqbh3#

我非常感谢任何形式的反馈——它们甚至可以不是最小限度的笑声😄

v2g6jxz6

v2g6jxz64#

一个有用的观察是,这个问题可以通过单个方差注解来解决

  1. interface Observable<in T> {

这意味着我们可能测量方差的方法是错误的。

axzmvihb

axzmvihb5#

我非常感谢任何形式的反馈——它们甚至可以不是那么微不足道的笑声😄
是的。这个只是一些内部团队已经生产了一个管道,其中包含了一些相当复杂的TS类型,推理以一种新的方式中断了。我会更多地关注代码库中的整体编译问题,并在相关时尝试突出其他类似的问题。

cgfeq70w

cgfeq70w6#

这改变了行为,即使在5.5中也是如此:

  1. interface Observable<T> {
  2. pipe<R>(op: OperatorFunction<T, R>): Observable<R>;
  3. }
  4. type OperatorFunction<T, R> = (source: Observable<T>) => Observable<R>;
  5. -declare function tap<T>(next: (value: T) => void): OperatorFunction<T, T>;
  6. +interface UnaryFunction<T, R> { (source: T): R; }
  7. +declare function tap<T>(next: (value: T) => void): UnaryFunction<Observable<T>, Observable<T>>
  8. declare const obs: Observable<{ a?: string; b?: number }>;
  9. function test(): Observable<{ a?: string }> {
  10. return obs.pipe(
  11. tap((tapped) => {
  12. tapped;
  13. // ^?
  14. }),
  15. );
  16. }

正如Ryan所怀疑的那样,TObservable<T>中被测量为具有VarianceFlags.Independent。这意味着它首先被测量为具有VarianceFlags.Bivariant(TS操场):

  1. interface Observable<T> {
  2. pipe<R>(op: OperatorFunction<T, R>): Observable<R>;
  3. }
  4. type OperatorFunction<T, R> = (source: Observable<T>) => Observable<R>;
  5. type Test1 = Observable<string | number> extends Observable<string> ? 1 : 0;
  6. // ^? type Test1 = 1
  7. type Test2 = Observable<string> extends Observable<string | number> ? 1 : 0;
  8. // ^? type Test2 = 1

pipe声明为属性而不是方法并不会改变这一点(TS操场)。
显然,当我们使用基于类型参数或基于结构的推断时,我们在这里得到了不同的结果。现在,我将研究我的PR中后者发生了什么变化。

展开查看全部
mccptt67

mccptt677#

顺便说一下,我已经发现了一些与此问题相关的其他新的编译问题。一旦有了这个PR的新5.6.0构建,我可以看到它是否解决了我之前看到的其他新问题。在这个例子中,基本上,推断似乎正在从类型中删除可选参数或将它们变为必需参数。我没有深入研究过这个问题。如果这个PR不能解决这个问题,我会尝试将其简化为一个可复现的问题。

v8wbuo2f

v8wbuo2f8#

你能尝试在#59709(评论)上构建吗,看看是否解决了你的问题?

laximzn5

laximzn59#

嘿,确认这个修复确实解决了这里指出的特定问题。
然而,我仍然看到其他与推理相关的新bug,希望这个修复能够解决它们。我会尝试在TS Playground中构造这些错误的复现,并提交新的issue。

相关问题