Skip to content

typeof Foo['bar'] has strange precedence #19707

Open

Description

Type queries combined with indexed access types currently produce a parse tree that is surprising in its behavior.

One would think that typeof Foo['bar'] would be parsed as typeof (Foo['bar']), which would really be something like typeof Foo.bar.

That's not the case. It's actually parsed as (typeof Foo)['bar'].

Conveniently, it seems that semantically (when type-checking) these are identical, but it seems strange for syntactic consumers. Do we believe this is currently working as intended?

Activity

  1. changed the title [-]typeof Foo['bar'] is parsed strangely[/-] [+]typeof Foo['bar'] has strange precedence[/+] on Nov 3, 2017
  2. mhegazy commented on Nov 7, 2017

    @mhegazy
    Contributor

    It should have the same precedence as in an expression. but this is a breaking change, and so far there is no functional impact of this on the output. marking it as a revisit for now.

  3. RyanCavanaugh commented on Jun 23, 2021

    @RyanCavanaugh
    Member

    Seems too late to change this now.

  4. DanielRosenwasser commented on Jul 1, 2021

    @DanielRosenwasser
    MemberAuthor

    Worth reconsidering in my opinion #44857

    I kind of doubt anyone would be broken by this change.

  5. fatcerberus commented on Jul 1, 2021

    @fatcerberus

    I remember discovering this a while back and was quite surprised that the relative precedence for typeof vs. [] in a type context was the exact opposite of runtime typeof.

    Worth noting though that I’ve seen a lot of examples given out on Gitter and Discord that freely do stuff like typeof Class["prop"], which is how I found out about the odd precedence in the first place. I prefer to add parentheses to minimize confusion, but from what I’ve seen, it is likely to be a breaking change if the precedence is changed now.

  6. sandersn commented on Jul 2, 2021

    @sandersn
    Member

    Seems easy enough to make this change and compile tonnes of code to see what the rates of breaks is.

  7. a-tarasyuk commented on Jan 21, 2022

    @a-tarasyuk
    Contributor

    TypeQuery is parsed as EntityName. Therefore, currently we can only use the following names in TypeQuery: a (Identifier), a.b (QualifiedName).

    function parseTypeQuery(): TypeQueryNode {
    const pos = getNodePos();
    parseExpected(SyntaxKind.TypeOfKeyword);
    return finishNode(factory.createTypeQueryNode(parseEntityName(/*allowReservedWords*/ true)), pos);

    Daniel Rosenwasser (@DanielRosenwasser) Do we need to parse it as an expression?

    /cc Ryan Cavanaugh (@RyanCavanaugh)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Effort: ModerateRequires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual".Experimentation NeededSomeone needs to try this out to see what happensHelp WantedYou can do thisRevisitAn issue worth coming back toSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions