Skip to content

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

Open
@jquense

Description

@jquense

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions