Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add asyncness to semantic highlighting #57593

Open
6 tasks done
OldStarchy opened this issue Mar 1, 2024 · 1 comment
Open
6 tasks done

Add asyncness to semantic highlighting #57593

OldStarchy opened this issue Mar 1, 2024 · 1 comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@OldStarchy
Copy link

OldStarchy commented Mar 1, 2024

πŸ” Search Terms

"expose type syntax highlight", "semantic syntax highlighting for promise", "highlight variables based on type"

βœ… Viability Checklist

⭐ 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)

	"editor.semanticTokenColorCustomizations": {
		"[Default Dark Modern]": {
			"rules": {
				"*.async": {
					"underline": true,
				},
			},
		}
	},

But this falls over in a few places

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

const prom = bar.doThing(); // <- prom is not underlined

console.log('doing something else");

await prom;

image

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

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

function getUserData(): Promise<User> | null {
  if (!db.isConnected()) return null;

  return db.getUser(ctx.currentUserId);
}

also

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? ' '
@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature labels Mar 1, 2024
@RyanCavanaugh RyanCavanaugh changed the title Expose type information to syntax highlighter Add asyncness to semantic highlighting Mar 1, 2024
@OldStarchy
Copy link
Author

Another use case relevant to the original title of this issue "Expose type information to syntax highlighter" being able to mark functions that mutate / return this different to those that are "const" and return a new value, this would help to catch errors like

const normalized = vec.normalize();

console.log(normalized === vec); // true (woops, needed .clone())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants