使用逻辑赋值时如何保留类型保护缩小?

问题描述

这是一个有点人为的问题示例(在真实世界版本中,tmp 重新分配用于深层嵌套对象遍历):

type F = () => number;

type R = {
  [ x: string ]: R | F | undefined
}

const isFunc = <T extends (...args: any[]) => any>(maybe:unkNown) : maybe is T => typeof maybe === "function";

const check = (i: R) => {

  let tmp:R = i;

  let curr = tmp["something"];

  if( isFunc<F>(curr) ) return;

  curr // R | undefined,expected

  tmp = curr || (curr = {}); //ok,expected

  tmp = curr ||= {}; //Index signature is missing in type 'F'

};

如您所见,在类型保护之后,curr 被正确地缩小为 R | undefined。之后,我将 tmp 重新分配给 curr 并将后者认为一个空对象(如果缺少)。

现在,如果我使用旧的 A || A = B 方法,逻辑 OR 左侧的 curr 会正确推断为 R | undefined。但是,如果我使用逻辑 OR 分配使意图更清晰,则 curr 被推断为 R | F | undefined。这显然会导致错误,因为 F 不可分配给 R

那么,问题是 - curr 在第二种情况下失去缩小的原因是什么?

Playground

解决方法

在源存储库中将此作为 issue 提交后,该行为被确认为错误(更像是当前的限制,因为在使用逻辑赋值运算符而不是短-使用逻辑运算符进行循环赋值)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...