Repository: TypeScript
Issue: feat(auto): reference own type in type declaration
Labels: Suggestion,Awaiting More Feedback

# Suggestion

Similarly to C++, having an auto type that would infer the type of a variable and that would be usable in its type declaration.

## 🔍 Search Terms

auto in type declaration

## ✅ Viability Checklist

* [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

Currently, there isn't a really neat and simple way of catching the type of a variable in its type declaration, which can be quite annoying when we want that variable to have other allowed types alongside with its original type, without needing to declare it as `any` or typing explicitely its type.

## 📃💻 Example and use cases

Let's say you're working with a library that deals with a lot of types
![image](https://user-images.githubusercontent.com/59736843/168492715-b808e2dc-a93b-4ac0-8198-3ad4e5eb897f.png)
In this example I'm using mongoose, and as you can see, certain type declarations don't even fit on my screen!

Now, let's say that you want to call one of the methods in this screenshot and register its value in a variable, but allow another type to go along with it, like for eg. a string, or to allow it to also be null? 

The only 3 ways you could do this right now in typescript is to either;
- Declare your variable as of the `any` type, which isn't really safe
- Using the ReturnType generic to get the return type of the method you're calling, ~~but which wouldn't even work out of the box because in this example the method we're calling is async and we're awaiting it, which returns the non promised type but... ReturnType gives us back a promise~~
- Copy the entirety of the type declaration (disastrous)

Oh and this example is only for when dealing with functions, what would you do if you were dealing with an object? You can't use ReturnType so you'd have to either copy it's type name or define it as `any`

On top of that, writing `Awaited<ReturnType<typeof fn>>` is much more longer than just using auto, and readability and clarity take a hit
```ts
// can be confusing and still brings up the concern of having
// long type names
// repeated code, we would need to change typeof bar and awaited if we 
// were to call another function
let foo: Awaited<ReturnType<typeof bar>> | null = await bar();
// vs
let foo: auto | null = await bar();
```

### Introducing auto would allow us to catch the type name of our variable and be able to mess with its type declaration

```ts
// Right now, the only way we can allow our variable x
// to be either a number or a string is 
let x: number | string = 5;
// We can't guess our type and do conditional typing at the same time
// In this example, it's not that big of a deal because we're dealing with a primite type but what if we were dealing
// with something with a large type name, or something that has multiple types?

// We could just do
let x: auto | string = 5;
// Which would also apply to our mongoose usecase
let x = auto | null = someMongooseFunctionThatReturnsA2kmWideTypeName();
```