Reputation: 9310
Image I have this little class with 2 static methods. Like this I can chain the methods as I want.
class MyClass {
static x() {
console.log("x");
return this;
}
static y() {
console.log("y");
return this;
}
}
MyClass.x().y();
If I wanted to add typings for the 2 methods how would the typings look like? In other words how can I define the correct return type?
class MyClass {
static x(): MyClass {
console.log("x");
return this;
}
static y(): MyClass {
console.log("y");
return this;
}
}
MyClass.x().y();
This doesn't work but hopefully shows what I mean.
Upvotes: 1
Views: 873
Reputation: 327849
The type named MyClass
corresponds to an instance of the MyClass
class, and as such does not have the static methods such as x
or y
.
Inside a static method implementation, this
refers to the constructor itself, which (as long as you don't have subclasses to worry about) will be the value named MyClass
. The type of the MyClass
constuctor is not MyClass
, but typeof MyClass
, using the Typescript typeof
type query operator.
If you use IntelliSense to inspect the return types inferred for x()
and y()
in your example code, you'll see:
class MyClass {
// (method) MyClass.x(): typeof MyClass
// ↓
static x() {
console.log("x");
return this;
}
}
If you really want to annotate the type for some reason, typeof MyClass
is potentially the right answer:
class MyClass {
static x(): typeof MyClass {
console.log("x");
return this;
}
static y(): typeof MyClass {
console.log("y");
return this;
}
}
Note that things get a bit trickier if you have subclasses and you want to capture the fact that subclasses have inheritance on the static side too:
class YourClass extends MyClass {
static z = 123;
}
YourClass.x().z // error!
// ---------> ~
// not known to exist by TypeScript but exists at runtime
You probably don't care about that, but if you do it's an outstanding issue in TypeScript; see microsoft/TypeScript#5863 for discussion and workarounds. More information available upon request.
Upvotes: 2