-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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 type system to represent this
in function inputs/outputs
#285
Comments
Use case ported : interface Base{
clone():Base;
}
interface Child extends Base{}
var child:Child;
var anotherChild = child.clone(); // Base. Should be Child. With interface Base{
clone<this T>():T;
}
interface Child extends Base{}
var child:Child;
var anotherChild = child.clone(); // Child Syntax is up for debate. But I believe |
+1 for It wouldn't solve #229 or the OP, which are more for callbacks and handlers with changed scope. |
This is not different from #229 at all (as far as I can see). I must, however, note that the example in your comment is needlessly narrowed to a special case. I would rewrite it something like this:
|
Forgot to add an opposite example:
|
@danquirk that issue is more focused on interface Base{
clone<this T extends Base>():T;
}
interface Child extends Base{}
var child:Child;
var anotherChild = child.clone(); // Child For a demo of function input consider interface Base{
merge<this T extends Base>(other:T):T;
} |
@basarat right, but if we go as far as @RyanCavanaugh suggests in that issue and consider how it affects assignability with function types then allowing it to be used in other signature positions for assignability is likely a small additional step. |
@danquirk agreed this can be marked a duplicate 👍 |
There are two very different suggestions going on here that I don't want to conflate. The first is whether or not you can accurately represent function createClone<T>(t: T): T {
return t; /* TODO: science! */
}
class Animal {
clone(): this { return createClone(this); }
// ~~~~
}
class Dog extends Animal {
woof(): void { }
}
var x = new Dog();
x.clone().woof(); // Should not error; `clone` currently returns `Animal` and causes error The other issue is the type of $('li').each(function() {
// http://api.jquery.com/each/
console.log(this.nane); // Should be an error
~~~~ type of 'this' should be HTMLElement here
}); |
this
as a function type
this
as a function typethis
in function inputs/outputs
I'm pretty sure that we on the team understand it, but let me just be clear on the fact that allowing Consider the following: class A {
a: number;
// This would *clearly* be the ideal usage of 'this'-types as a parameter.
compare(other: this): boolean {
return this.a === other.a;
}
}
class B extends A {
b: number;
// Now override A's 'compare'.
compare(other: this): boolean {
return this.b === other.b;
}
}
var a1: A = new A();
var a2: A = new B();
a2.compare(a1); So this would fully type check, but So really, I'd prefer that if we ever did this, we restricted |
It seems that it can be a problem even without class A {
a = 1; // default
// This would *clearly* be the ideal usage of 'this'-types as a parameter.
compare(other: A): boolean {
return this.a === other.a;
}
}
class B extends A {
b = 2; // default
// Now override A's 'compare'.
compare(other: B): boolean {
if (!("b" in this) || !("b" in other))
throw new Error("It seems there is an error...");
return this.b === other.b;
}
}
var a1: A = new A();
var a2: A = new B();
a2.compare(a1); // This still throws a runtime error but not a compile-time error. |
I don't think that example is coherent either way, since |
Defining the type of |
@DanielRosenwasser Only allowing I would propose the keyword to be Any news on when this feature might land in a stable release? |
Would very much like an update into this issue |
Hey @bluong, I think we're still interested in it, but ES6 work has dominated much of our time. We're still also lacking a solid proposal. |
I'd love to see readStream.on('error', ...).pipe(writeStream); The biggest issue for class Chainer {
doSomething(...) : this {
// do something
return this;
}
} Classes with chaining methods can be safely inherited from while maintaining For class Cloner {
clone() : this<Cloner> {
return new Cloner();
}
}
class DerivedCloner extends Cloner {
clone() : this<DerivedCloner> {
return new DerivedCloner();
}
} It should be possible for these return types to be used to override each other, as well as specifying the base class or derived class as the return type (instead of |
any news on this issue? |
+1 |
this is now tracked by #3694 |
The early discussions about generics had this feature outlined, but it never made it into the final version for some reason. Meanwhile, it would be extremely helpful in some cases. The use case that it most dear to my heart is Knockout:
The text was updated successfully, but these errors were encountered: