Repository: TypeScript
Issue: Add `async`ness to semantic highlighting
Labels: Suggestion,Awaiting More Feedback

### 🔍 Search Terms

"expose type syntax highlight", "semantic syntax highlighting for promise", "highlight variables based on type"

### ✅ 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 isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- [X] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

### ⭐ Suggestion

Expose (some) type information to the syntax highlighter for semantic styling so we can highlight variables / function calls of particular types.

### 📃 Motivating Example

Hungarian notation has long since marked as something to be avoided, yet a common practice I see is naming async functions with an `Async` suffix, or with an `await` prefix.

```
fs.readFile();
await fs.readFileAsync();

await awaitMyFunction();
```

This indicates that whether or not something returns a promise is important enough that we're marking async functions with these prefixes/suffixes.

Hungarian notation went away because IDE's improved and we could start to rely on it to give us type information (on hover) and via type checking.

While researching this I stumbled upon the semantic highlighting config in VSCode and decided to take a leaf out of rusts book which underlines `mut` values and tried to apply an underline to any variable `T` where `T extends Thenable<any>`.

However the best I could get was to mark functions tagged as async as this is the only information available to the syntax highlighter (as seen by running the "Developer: Inspect Editor Tokens and Scopes" command)

```json
	"editor.semanticTokenColorCustomizations": {
		"[Default Dark Modern]": {
			"rules": {
				"*.async": {
					"underline": true,
				},
			},
		}
	},
```

But this falls over in a few places

```ts
interface Foo {
  doThing(): Promise<string>;
}

class Bar extends Foo {
  async doThing() { // <- underlines correctly here
    return 'hi';
  }
}

const bar = new Bar();
bar.doThing(); // <- and here

const barAsFoo: Foo = bar;

barAsFoo.doThing(); // <- no underline here.
```

It also doesn't do anything for thenable valued variables

```ts
const prom = bar.doThing(); // <- prom is not underlined

console.log('doing something else");

await prom;
```

![image](https://github.com/microsoft/TypeScript/assets/15243523/f59d48d8-5abc-4e4d-ad1b-49cad91305e6)

In my head, the ideal situation is that a textmate modifier is added to any variable whose value (or method whose return type) exclusively extends `Promise` (or `Thenable`). That way `prom` would be underlined.

I understand there will be some complexities and many edge cases for figuring this out; its not necessarily true that `Promise` refers to a promise

```ts
type Promise<TAction extends string = string> = `I promise I will ${TAction}`;

function getActionFromPromise(prom: Promise) {
  const match = /^I promise I will (.*)$/.exec(prom);

  return match[1];
}

console.log(getActionFromPromise('I promise I will not write esoteric code'));
```

or

```ts
function getUserData(): Promise<User> | null {
  if (!db.isConnected()) return null;

  return db.getUser(ctx.currentUserId);
}
```

also

```ts
function doNothing<T>(val: T): T {
  return val;
}

const foo = doNothing(Promise.resolve());
```

There may be ways around these problems (maybe something like `T extends Promise<any> ? Promise<any> extends T ? true : false : false`)

### 💻 Use Cases

1. What do you want to use this for? As mentioned in "motivating example"
2. What shortcomings exist with current approaches? ' '
3. What workarounds are you using in the meantime? ' '