Skip to content

ES6 Class: asserts this is Type raises error when variable containing instance is type narrowed #54591

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

Open
protango opened this issue Jun 9, 2023 · 1 comment
Labels
Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases
Milestone

Comments

@protango
Copy link

protango commented Jun 9, 2023

Bug Report

🔎 Search Terms

  • Error: "Assertions require every name in the call target to be declared with an explicit type annotation"
  • Assertation function as class method
  • Type narrowing class and then calling assertation method

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about this

⏯ Playground Link

Playground link with relevant code

💻 Code

class MyClass {
	public assertIsMyClass(): asserts this is MyClass {
		if (!(this instanceof MyClass)) {
			throw new Error('this was not of type MyClass');
		}
	}
}

const maybeMyClass: MyClass | undefined = new MyClass();

if (maybeMyClass) {
	// This fails with error:
	// Assertions require every name in the call target to be declared with an explicit type annotation.(2775)
	maybeMyClass.assertIsMyClass();

	// But if we simply assign to a new variable without the optionality, it's fine:

	// this line works because we have narrowed the type through the if statement above
	const definitelyMyClass: MyClass = maybeMyClass; 
	// This raises no error even though it's equivalent to the first attempt
	definitelyMyClass.assertIsMyClass();
}

🙁 Actual behavior

Calling the class method assertation function raises error: "Assertions require every name in the call target to be declared with an explicit type annotation.(2775)"

🙂 Expected behavior

It should pass validation and narrow to the type given in the assertation.
This is because it will have this behavior if you simply assign to a new variable with a new type annotation (but which is equivalent to the narrowed type at that point).

@jcalz
Copy link
Contributor

jcalz commented Jun 9, 2023

Essentially a duplicate of strongly related to #36931

It's an unfortunate design limitation of TypeScript. Since maybeMyClass was narrowed to MyClass without being explicitly annotated as MyClass, the compiler refuses to analyze it.

@RyanCavanaugh RyanCavanaugh added Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases Help Wanted You can do this labels Jun 19, 2023
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Jun 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Help Wanted You can do this Possible Improvement The current behavior isn't wrong, but it's possible to see that it might be better in some cases
Projects
None yet
Development

No branches or pull requests

3 participants