Skip to content
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

Allow assignment of void returning functions to appropriate construct signature types #2310

Closed
danquirk opened this issue Mar 12, 2015 · 2 comments
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript

Comments

@danquirk
Copy link
Member

Consider an existing JS constructor function

var Foo = function (x,y) { 
    this.x = x;
    this.y = y;
}
var foo = new Foo(1,2);

This is allowed in TypeScript due to a specific exception which allows new to be called on non-constructor functions only if they're void returning. Now if you want to more strongly type this code, but without converting to full on classes yet, we do not allow you to do so in a fully typesafe manner:

interface FooInstance {
    x: number;
    y: number;
}
interface FooConstructor {
    new (x: number, y: number): FooInstance;
}
// this an error, new(x,y)=>FooInstance is not assignable to (x,y)=>void
var Foo: FooConstructor = function (x,y) {
    this.x = x;
    this.y = y;
}
var foo = new Foo(1,2);

We require you to cast the constructor function to any or Function in order for it to be assignable to the FooConstructor interface.

Given that we've made an exception for void returning functions already in order to accommodate this pattern it doesn't seem crazy to make one more exception for them through the assignability relation in order to complete the desired scenario.

See #2299 for another example from a customer.

@danquirk danquirk added the Suggestion An idea for TypeScript label Mar 12, 2015
@mhegazy mhegazy added the In Discussion Not yet reached consensus label Dec 9, 2015
@RyanCavanaugh RyanCavanaugh added Declined The issue was declined as something which matches the TypeScript vision and removed In Discussion Not yet reached consensus labels Jan 5, 2016
@RyanCavanaugh
Copy link
Member

If anything we'd rather remove the ability to new void functions. The inconsistency is unfortunate but we didn't want to add a large type safety hole for the sake of consistency with a facet we don't even like in the first place.

@nycdotnet
Copy link

Hi Ryan,

Very coincidentally, this came up again for me today while refactoring an old code base - this time with an Angular 1.x View Model written in the "call new on a void function to make a constructor" style that has fallen out of favor today, but is still floating around (it remains part of the Knockout tutorial at http://learn.knockoutjs.com/#/?tutorial=collections).

Anyway, we've gained the ability to strongly type this within a function since this issue was considered; with a strongly-typed this, I don't believe that this JS pattern represents a type-safety hole anymore. The rule could be: if a void function with an explicitly-typed this is called with new, the return type of the expression is the same type as the explicit this within that function, and error TS7009 does not apply.

Thanks either way!

@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants