Skip to content

Cannot use 'new' error on intersection type with constructor #17388

Closed

Activity

  1. RyanCavanaugh commented on Jul 25, 2017

    @RyanCavanaugh
    Member

    This regressed between 2.1 and 2.2

  2. MrMatthewLayton commented on Mar 27, 2018

    @MrMatthewLayton

    Mohamed Hegazy (@mhegazy) Ryan Cavanaugh (@RyanCavanaugh)

    Adding this from StackOverflow for completeness

    I have identified a problem when using intersection types in TypeScript...

    I have three type aliases:

    • Prototype<T> - expresses an object/class that has a prototype property.
    • DefaultCtor<T> - expresses an object/class with a default constructor.
    • ParameterizedCtor<T> expresses an object/class with a parameterized constructor.

    I have tried these intersection permutations:

    • Prototype<T> & DefaultCtor<T> - works fine.
    • Prototype<T> & ParameterizedCtor<T> - raises a compiler error.

    Example

    type Prototype<T> = {
        prototype: T;
    }
    
    type DefaultCtor<T> = {
        new(): T;
    }
    
    type ParameterizedCtor<T> = {
        new(...args: any[]): T
    }
    
    function makeDefault<T>(ctor: Prototype<T> & DefaultCtor<T>): T {
        return new ctor();
    }
    
    function makeWithArgs<T>(ctor: Prototype<T> & ParameterizedCtor<T>, ...args: any[]): T {
        return new ctor(...args);
        // ERROR: Cannot use 'new' with an expression whose type lacks a call or construct signature.
    }
    

    Try it in the Playground

    Error
    The error occurs with the Prototype<T> & ParameterizedCtor<T> intersection:

    Cannot use 'new' with an expression whose type lacks a call or
    construct signature.

    Why does the TypeScript compiler recognise the Prototype<T> & DefaultCtor<T> intersection type as having a constructor, but not the Prototype<T> & ParameterizedCtor<T> intersection type?

  3. gssjr commented on Jun 15, 2018

    @gssjr

    I may be running into this as well. Here's my example:

    declare namespace __example {
      interface A {
        aProp;
      }
    
      interface AConstructor {
        new(): A;
      }
    
      export const A: AConstructor;
    }
    
    class MyClass {
      myInvalidFunc = (A: __example.A) => {
        // [ts] Cannot use 'new' with an expression whose type lacks a call or construct signature.
        const a: __example.A = new A();
      }
    
      myValidFunc = (A: __example.AConstructor) => {
        const a: __example.A = new A();
      }
    }
    
  4. weswigham commented on Jun 15, 2018

    @weswigham
    Member

    myInvalidFunc = (A: __example.A) => {
    // [ts] Cannot use 'new' with an expression whose type lacks a call or construct signature.
    const a: __example.A = new A();
    }

    This is correct. __example.A isn't a constructor.

  5. 1 remaining item

  6. added a commit that references this issue on Oct 11, 2018
    a8b6164
  7. mattmccutchen commented on Oct 11, 2018

    @mattmccutchen
    Contributor

    A silly mistake in the logic for handling mixin classes. Fix is in #27701.

  8. added a commit that references this issue on Feb 9, 2019
    a724427
  9. added a commit that references this issue on Mar 12, 2019
    ab81536
  10. 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