TypeScript无法从带有promise的while循环条件中推断出正确的类型,

iecba09b  于 4个月前  发布在  TypeScript
关注(0)|答案(5)|浏览(52)

🔎 搜索词

while循环条件中的Promise

🕗 版本与回归信息

  • 在所有我尝试的版本中,我都发现了这个问题,并查阅了关于“非错误bug”的FAQ条目。

⏯ Playground链接

https://www.typescriptlang.org/play?ts=5.2.0-dev.20230807#code/GYVwdgxgLglg9mABAZwDYFN0AcAUBbZALkTBDwCN0AnASmIAUq48Zl0AeKKkdAPkQDeAKESIq6KCCpIw6AO6JGzVhy49eOAIaIAvPzZQAKjDzo4IKDhw1d-TTjXoaAGkQEaNIQF8hQzcgBPSERQSFgERHQAD008LAwARmsGJhY2dmQuGDAAc35hAEgMKEQAN01UHmJMqmycxAAfRHAAE3RgbPQWoQK5AAsYDEQHbidBHoLNOU0YErRMXABWAAZVzwKC8sr0XUQAckW9ifJxTQBrHp8C8UlpMoqeb19-IIgQ8Gh4JGjY+PQAJmSilSKgyWVy+R6xXu22q4PqTVa7U63V6AyGWmmsxQGGwOBWaxshU2Dx2On2h2OpwuBSuNykSC2jy8QA

💻 代码

function sleep(ms: number): Promise<true> {
  return new Promise<true>(a => setTimeout(() => a(true), ms))
}

async function example1(): Promise<string> {
	let value: string | undefined
	while (true) {
		await sleep(5000)
		value = '5'
		break
	}
	return value
}

async function example2(): Promise<string> {
	let value: string | undefined
	while (await sleep(5000)) {
		value = '5'
		break
	}
	return value
}

🙁 实际行为

在example2中,TypeScript无法推断出 value 的类型,它应该现在是一个字符串,而不是 undefined,仅仅因为在while循环中的返回true的Promise已经被移动到了while条件中,而不是while循环体的内部。

🙂 预期行为

预期的行为应该是,TypeScript应该能够在return语句处推断出它仍然是一个字符串,就像在example1中一样。

6ju8rftf

6ju8rftf1#

可能存在重复的#30551?
#29323 然后

piah890a

piah890a2#

await 在这里是一个误导因素- if (true)if (trueTypedValue) 在CFA中受到不同的处理,我记得是这样的。

wgeznvg7

wgeznvg73#

解释:#29323 (评论)
基本上,这是一个设计限制,不太可能轻易修复。CF节点是在类型已知之前保守地创建的。像if (true)if (false)这样的东西之所以能工作,是因为它们在语法上是特殊情况。
我确实质疑为什么你会写这样的代码 - 如果你知道条件总是为真,为什么还要让它成为条件语句?

pgvzfuti

pgvzfuti4#

我不太确定我是否完全同意我之前的解释适用于这个案例。CFA节点确实存在,在评估可达性时,我们可以在这种情况下解决类型而不会出现循环。
然而,显然这并不是一个非常有用的修复方法来解决“实际”代码的问题。

m528fe3b

m528fe3b5#

我确实会质疑你为什么要写这段代码——如果你知道条件总是为真,为什么还要在一开始就让它有条件?
我喜欢把sleep命令放在while条件中,以便编写更少的代码。我总是让我的sleep命令在我想用它作为某个条件的情况下返回true。
然而,如果比如说,我想要一个do-while循环,而该循环的主体有几个条件,其中一些调用continue,那么我不希望把sleep函数仅仅放在所有那些continue关键字上方。

相关问题