Skip to content

Assertion function methods complains about missing annotation even with explicit annotation #39361

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
jquense opened this issue Jul 1, 2020 · 2 comments
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

@jquense
Copy link

jquense commented Jul 1, 2020

This may be working as intended but the error message is at least unclear for this case. It's not obvious why explicit annotation with a Union is different than explicit annotation with a class type.

TypeScript Version: 3.9.4

Search Terms:

  • assertion function union
  • assertion function

Code

type Pet = Cat | Dog;

type Filter<V extends Pet, T extends 'dog' | 'cat' > = V extends { type: T } ? V : never

abstract class Base {
    abstract type: 'dog' | 'cat'   
  
    assert<T extends 'dog' | 'cat'>(this: Pet, type: T): asserts this is Filter<Pet, T>  {
        if (this.type === type) return
        throw new Error('nope')
    }
}

class Dog extends Base {
    type = 'dog' as const
    bark() { }
}       
class Cat extends Base  {
    type = 'cat' as const
    meow() { }
}

const a: Pet = new Dog() as any

const b: Dog = new Dog() as any

a.assert('dog')
a.bark()

b.assert('dog')
b.bark()

Expected behavior:

a.assert() to narrow the type and not complain about an explicit type annotation

Actual behavior:

a.asserts is marked as implicitly typed

Playground Link:

https://www.typescriptlang.org/play/index.html?ssl=38&ssc=9&pln=3&pc=1#code/LAKFBcE8AcFMAIAKtzwLzwMIENUB94ARAewHMBuUCGBAMQEsAbcWAJwB4A1eWADxYB2AEwDOSFABp4AFR79YwsQHIhZJfAJKAxrnUA+dPG59Bo+AG94UOAC4Z8AL7wA-Efh2BsAG5sqIbABGIuCs2FqoWozYImIAQtEI5qDwKfCBwaHhVjR2Kmoa8Nq6qcnwpSnRImzg7LImCmZ5pOqaOuBKegAU4AAW9CJ2yOBS1rB20gCUdpXVYr398AsMzGzsQ1LSBhblqSn0AGbw3X0iAHSj6GgYoxPwrCgArqwCO7u9rMQA7vCe3wCirA+rE6SgExDgSgmOwcoBhYBA+weAnC9GIAjSMWq0hotTkpmUqmaBSK7S6XkGkmythkUwxVVY4DEXkWYmWLA46xkWySIF2ByOXnONEu1xot3u4CeL15qXeXx+sH+gOIwNB4NgkNhfkilSIZDxDTiCW2MpSFwwTXU0XgWjRwR2AWwrAA1p1bpY4U5dilQDqYlhcAbFPB4lUUjy3sKLW0rWJbQJ7ab4ABbWBfN0WRxa+G+u2obAU1AYX560gZ63YASQXMJ1ABOwkUiGEuN8tiSvV+HYU4zBkgwma-ynR0ut1+AI9zF9y1QkATkeu2dAA

Related Issues:

#36931
#37241

@jquense jquense changed the title Assertion function methods complains about missing annotation with explicit Union annotation Assertion function methods complains about missing annotation even with explicit annotation Jul 8, 2020
@RyanCavanaugh RyanCavanaugh added 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 labels Jul 9, 2020
@RyanCavanaugh
Copy link
Member

The error is correct; Pet does not have an explicit type annotation for its assert member because its assert member is only synthesized from its union constituents. The implied suggestion is to iterate through any explicitly-declared unions to see if each of its constituents has an explicitly-annotated asserts method. This might be tricky or might be straightforward; I'm not sure.

@jquense
Copy link
Author

jquense commented Jul 9, 2020

My guess was the error is correct, I find it confusingly worded for this case. I read "explicit" as "has a type annotation", which this does.

The implied suggestion is to iterate through any explicitly-declared unions to see if each of its constituents has an explicitly-annotated asserts method.

That would be awesome yes.

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