Skip to content

Overloads with newable signatures not chosen #24428

@rkirov

Description

@rkirov

TypeScript Version: 3.0.0-dev.201xxxxx

Search Terms: newable signature

Code

declare function construct<T>(ctor: new(...args: any[]) => T): T;
declare function construct<T>(ctor: Function): T;

class C {
  constructor(public x: string) {};
}

const instance = construct(C);
instance.x;

Expected behavior:
The first overload is chosen, instance is of type C, thus no error at instance.x.

Actual behavior:
Second overload is chosen, instance is of type {} (as per underspecified generics rules), error at instance.x because {} has no x.

Playground Link: http://www.typescriptlang.org/play/#src=declare%20function%20construct%3CT%3E(ctor%3A%20new(...args%3A%20any%5B%5D)%20%3D%3E%20T)%3A%20T%3B%0D%0Adeclare%20function%20construct%3CT%3E(ctor%3A%20Function)%3A%20T%3B%0D%0A%0D%0Aclass%20C%20%7B%0D%0A%20%20constructor(public%20x%3A%20string)%20%7B%7D%3B%0D%0A%7D%0D%0A%0D%0Aconst%20instance%20%3D%20construct(C)%3B%0D%0Ainstance.x%3B%0D%0A

Some odd things that I don't fully understand:

  • only happens when we turn on strictFunctionTypes
  • doesn't happen if C has no ctor arguments.
  • if there is a single overload for the newable signature only, it is chosen fine.

Note this is based on real world code in angular typings.
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/8091b4653666317dc94a3ede9f84d3114c67db81/types/angular/index.d.ts#L1394

One workaround is to change typings not to use underspecified Function type.

Metadata

Metadata

Assignees

Labels

Working as IntendedThe behavior described is the intended behavior; this is not a bug

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions