Skip to content

Extracting the instance type from the ctor value that works for abstract classes #26829

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
3 of 4 tasks
rkirov opened this issue Aug 31, 2018 · 2 comments · Fixed by #36392
Closed
3 of 4 tasks

Extracting the instance type from the ctor value that works for abstract classes #26829

rkirov opened this issue Aug 31, 2018 · 2 comments · Fixed by #36392
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript

Comments

@rkirov
Copy link
Contributor

rkirov commented Aug 31, 2018

Search Terms

abstract class constructor type

Suggestion

Currently, I think there is no way to express the type of constructor functions for abstract classes. On one hand that is correct because 'new' cannot be called on them. However, sometimes there is a need to tie an instance of the abstract class with the constructor function for type-checking.

Use Cases

DI helper functions in angular and other frameworks.

Examples

// Angular calls this Type<T>
// https://github.com/angular/angular/blob/master/packages/core/src/type.ts#L25
interface Factory<T> extends Function {
  new (...args: any[]): T;
}

abstract class AC {
  abstract x: number;
}

class C extends AC {
  x = 0;
}

// a DI-like system, that returns instance of C for get(C) and get(AC).
// The mechanism is left unspecified.
declare function get<T>(token: Factory<T>): T;

let x1 = get(C);
let x2 = get(AC);  // error, underlying issue is that AC is not assignable to Factory<AC>

Basically, this is asking for a mechanism to go from a value C, where C is a symbol for a class (abstract or not), to the type C.

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript / JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. new expression-level syntax)
@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. labels Aug 31, 2018
@mattmccutchen
Copy link
Contributor

Could you just use the prototype?

interface Factory<T> extends Function {
  prototype: T;
}

This doesn't work for generic classes, but I'm not sure how your proposal could either.

@rkirov
Copy link
Contributor Author

rkirov commented Sep 18, 2018

Closing this issue in favor of #24428. In practice both AngularJS and Angular DI types are written using an second overload to :any to handle the cases where the issue described above prevents from type checking :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants