Skip to content

Cannot define a union type with a new signature type #4067

Closed

Description

@tinganho

This currently gives me parse error:

class A {

}

function test(x: string | new() => A) {
                          ~~~~~~~~~~ parse error    
}

Though this works:

function test(x: new() => A) {

}

Activity

  1. RyanCavanaugh commented on Jul 29, 2015

    @RyanCavanaugh
    Member

    Due to parsing precedence, you have to write

    function test(x: string | (new() => A)) {
    }
  2. tinganho commented on Jul 29, 2015

    @tinganho
    ContributorAuthor

    Ok thanks, shouldn't it give me some kind of feedback on that?

  3. RyanCavanaugh commented on Jul 29, 2015

    @RyanCavanaugh
    Member

    Parser errors are best-effort because the fact that there's a parser error means we're really not sure what's going on or what the intended code was. The earliest error is "type expected", which is nearly (?) correct. I'm not sure what specifically we could do; maybe Cyrus Najmabadi (@CyrusNajmabadi) has some ideas.

  4. CyrusNajmabadi commented on Jul 29, 2015

    @CyrusNajmabadi
    Contributor

    we could technically parse a wider range of values when parsing the union type. We could then report an error afterwards with more detail. I wouldn't have a problem with that at all.

  5. CyrusNajmabadi commented on Jul 29, 2015

    @CyrusNajmabadi
    Contributor

    Note: it's necessary for precedence that we disallow this. Otherwise there's far too much ambiguity. For example, it would then get very tricky to have a rule to properly parse this:

    a: string | new() => B | C

    So it's better to use precedence to outright disallow call/construct signatures when parsing a union/intersection type and give the escape hatch of parenthesizing things if that's what you actually want.

  6. DanielRosenwasser commented on Jul 29, 2015

    @DanielRosenwasser
    Member

    I'd say that it's advantageous to users to disallow this, since we force writers to be explicit for future readers.

    But yes, I think parsing this and reporting an error would be helpful, such as:

    A function or constructor type literal must be explicitly parenthesized in a union or intersection type.
    

    or the following two separately:

    A function type literal must be explicitly parenthesized in a union or intersection type.
    
    A constructor type literal must be explicitly parenthesized in a union or intersection type.
    
  7. benliddicott commented on Sep 7, 2015

    @benliddicott

    Maybe just add: "(Tip: Do you need parentheses?)"

  8. jbondc commented on Sep 20, 2015

    @jbondc
    Contributor

    Hit this recently with intersection types. Patch (was a bit tricky) uses this message :
    Invalid type. To avoid ambiguity, add parentheses: '(new() => void)'

  9. added this to the milestone on Feb 22, 2016
  10. Andarist commented on Aug 1, 2023

    @Andarist
    Contributor

    Today this is reported nicely:

    Constructor type notation must be parenthesized when used in a union type.(1386)

    This matches Daniel's suggestion from the comment here so the issue can be closed, cc Jake Bailey (@jakebailey)

  11. locked as resolved and limited conversation to collaborators on Oct 21, 2025
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

    BugA bug in TypeScriptHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions