Repository: TypeScript
Issue: Infer array element type for newly created variable when assigning to a new empty array
Labels: Suggestion,Awaiting More Feedback,Experimentation Needed

# Suggestion


## 🔍 Search Terms
array assignment infer
empty array
<!--
  💡 Did you know? TypeScript has over 2,000 open suggestions!
  🔎 Please search thoroughly before logging new feature requests as most common ideas already have a proposal in progress.
  The "Common Feature Requests" section of the FAQ lists many popular requests: https://github.com/Microsoft/TypeScript/wiki/FAQ#common-feature-requests

  Replace the text below:
-->

List of keywords you searched for before creating this issue. Write them down here so that others can find this suggestion more easily and help provide feedback.

## ✅ Viability Checklist

<!--
   Suggestions that don't meet all these criteria are very, very unlikely to be accepted.
   We always recommend reviewing the TypeScript design goals before investing time writing
   a proposal for ideas outside the scope of the project.
-->
My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).


## ⭐ Suggestion

<!-- A summary of what you'd like to see added or changed -->

When creating an array variable using `const` or `let` and assign it to an array *after* another typed array variable, type should be inferred from the variable:

```ts
class Foo {

    foo: number[];

    doSomething() {
        const a = this.foo = []; // a is now any[] or never[]
        const b: number[] = this.foo = []; // b is number[] but we have to repeat the type declaration
    }

}
```

There seem to be inconsistency between IDEs as well, for VS Code it's `any[]` while for playground, it's `never[]`. See [my question on StackOverflow about this](https://stackoverflow.com/questions/69684939/why-doesnt-typescript-imply-array-type-when-assigning-to-a-new-empty-array)

## 📃 Motivating Example

Right now, the above code would result in compile error if `--noImplicitAny` is specified (at least for VS and VS Code). You also do not have strongly typed variables for the array's element. With this feature implemented, you can now write:

```ts
class Manager {

    foo: Employee[];

    doSomething() {
        const foo = this.foo = []; // a should be Employee[]

        for (let item of arr) { foo.push(item); }

        foo[0].role = "manager"; // Elements are now strongly typed.
    }

}
```

## 💻 Use Cases

I use this code a lot when writing HTML templates for small projects without frameworks like Angular. For example:

```
export class MyComponent extends HTMLElement {

    // Others
    items: ListItem[];

    set(list: ListItem[]) {
        // This would result in error currently in VS Code with noImplicitAny
        const items = this.items = [];
        for (let item of items) {
            // Other code
            items.push(item);
        }

        // Work with items
        for (let item of items) {
                // item is any currently, not ListItem
        }
    }
}
```