gpt4 book ai didi

typescript - 为什么 TypeScript 不能确定在检查未定义返回的 if 语句之后定义了变量

转载 作者:行者123 更新时间:2023-12-05 00:44:56 24 4
gpt4 key购买 nike

我正在使用 strictNullChecks 在 TypeScript 3.6.2 中进行编译启用。

假设我声明了一个可能 undefined variable :

let filename: string|undefined;

然后,回调可能会为其分配一个值,或者将其保留为未定义:
doIt(() => filename = "assigned");

现在我检查回调是否分配给 filename; otherwise,文件名 is undefined and I exit the program (return value of从不`):

if (filename === undefined) {
process.exit(0);
}

如果这个 if条件为假,这意味着 filename 必须有一个有效的字符串值,对吗?最后,我尝试使用我最确定的字符串:

console.log(filename.toUpperCase());

但是,我收到一个错误:
source/repro.ts:6:13 - error TS2532: Object is possibly 'undefined'.

6 console.log(filename.toUpperCase());
~~~~~~~~


Found 1 error.

据我了解,因为 if上面的语句有 never返回,这意味着程序在到达以下使用 filename 的行之前终止;因此, filename必须是字符串!我在这里错过了什么吗?为什么 TypeScript 还相信它 filename在永不返回之后仍然是未定义的吗?

对于复制,这里是完整的程序:

let filename: string|undefined;
doIt(() => filename = "assigned");
if (filename === undefined) {
process.exit(0);
}
console.log(filename.toUpperCase());
function doIt(fn: () => void) {
fn();
}

备注 : 我可以在我的真实程序中解决我的问题,因为我可以初始化 filename = "" ,并在 if 语句中检查它。但是,我想知道为什么这种特定方法不起作用。

编辑 : 这是我的 tsconfig.json .我在一个没有 tsconfig.json 的全新文件夹中尝试了这个例子我无法重现此错误。也许我的 tsconfig 中有什么问题,但我还没有确定:
{
"compilerOptions": {
"module": "commonjs",
"target": "es2017",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"declaration": true,
"alwaysStrict": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"noImplicitAny": true,
"strictBindCallApply": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"noUnusedLocals": true
},
"include": [
"source/**/*.ts"
]
}

最佳答案

这是 Typescript 3.6.3 及更早版本中的行为,但它实际上在 3.7.2 版中以您希望的方式工作;这是一个 Playground Link自己看看。如果使用菜单在版本之间来回切换,错误会出现并消失。
如果您的项目需要这样做,那么您可以升级 Typescript。

基本上,问题在于控制流图是在类型检查之前确定的,因此在形成 CFG(并检查可达性)时,事实是 exit返回 never不可用,因此 CFG 分支位于 exit继续调用 if 之后的代码语句,其中变量处于可能未定义的状态。
这是 raised as an issue on GitHub 2016 年 12 月,根据 a response in a different thread ,

#12825 Generalize handling of never for returns

  • The control flow graph is formed during binding, but we don't have type data yet
  • We could store all calls at each flow control point and then check them for never returns and check this info for computing types
    • Expensive!
  • Correct analysis would require multiple iterations

所以这些是它在 3.6.3 及更早版本中可能没有解决的一些原因。

关于typescript - 为什么 TypeScript 不能确定在检查未定义返回的 if 语句之后定义了变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59093500/

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