Create flag strictVariableInitialization

未关闭
#60,064 5 条评论 2 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
30/100
Issue 类型
功能
描述清晰度
描述清楚
活跃度
停滞
领域
compilers

调研方向

首先审查拟议的 strictVariableInitialization 行为及其提出动机的 Closure 示例,然后将其与 strictPropertyInitialization 进行比较。定义应如何处理可达代码路径和包含 undefined 的类型;当该提案的设计已经确定,并且编译器具有相应行为且不改变生成的 JavaScript 时,即视为完成。

由索引模型根据 Issue 内容生成。

描述

Awaiting More Feedback Suggestion
🔍 Search Terms

uninitialized variable, undefined, closure, strict property initialization,

✅ Viability Checklist
⭐ Suggestion

I would like to see a check that ensures that no variable whose type is not permitted to be undefined may remain uninitialized at the end of its scope.

📃 Motivating Example

TypeScript allows unsafety that can and does catch users by surprise when using variables in a closure. Normally, TS won't let you access an uninitialized variable:

function doSomething() {
   let foo: string;
   foo.toLowerCase(); // TS ERROR: Variable 'foo' is used before being assigned 
}

However, TypeScript optimistically assumes that variables are initialized when used in closures.

let foo: string;

function printFoo() {
    console.log(foo.toLowerCase());
}

printFoo(); // Uncaught TypeError: Cannot read properties of undefined (reading 'toLowerCase')

That's for good reason, but sometimes, as in the above case, this is provably unsafe, since foo is guaranteed not to be initialized.

The new flag "strictVariableInitialization" ensures that a variable must be initialized by the end of all reachable codepaths in its scope.

let foo: string; // (proposed) TS ERROR: `foo` is not initialized in all reachable codepaths 

function printFoo() {
    console.log(foo.toLowerCase());
}

printFoo()

Of course, variables whose type includes undefined are still permitted to be uninitialized.

let foo: string | undefined;

function printFoo() {
    console.log(foo?.toLowerCase());
}

printFoo();

This check is highly analogous to strictPropertyInitialization for classes.

💻 Use Cases

See https://github.com/typescript-eslint/typescript-eslint/issues/9565 for a somewhat-wordier proposal in typescript-eslint, and https://github.com/typescript-eslint/typescript-eslint/issues/4513 and https://github.com/typescript-eslint/typescript-eslint/issues/10055#issuecomment-2374797860 for cases where this has caused confusion in the wild.

In short, people who have written code that does check for initialization of non-nullable variables become confused by the linter informing them that the check is unnecessary according to the types, even though they can see that it is necessary at runtime:

let foo: Something

function useFoo() {
   if (foo != null) { // linter flags this condition as unnecessary since foo cannot be nullish
      foo.bar();
   }
}

The code should be rewritten as

let foo: Something | undefined

function useFoo() {
   if (foo != null) {
      foo.bar();
   }
}
主要语言
Go
星标
111k
派生
14.4k
平均合并
1 天 15 小时
30 天内合并 PR
106

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

microsoft/TypeScript 的其他 Issue

查看 microsoft/TypeScript 的全部 Issue

相似的 Issue

更多 Go Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。