I'm having problems understanding how to correctly type a constructor function in TS. I'm aware that a common answer would be to use a class, but I'm currently exploring TS features. In my tsconfig.json
I have noImplicitAny: true
.
My constructor function looks like this in JS:
function User(username) {
this.username = username
}
User.prototype.age = 57
My first attempt to type the functions relied on the TS docs that explain how to define call signatures:
interface IUser {
username: string;
age: number;
}
type UserConstructor = {
(username: string): void;
new (username: string): IUser;
}
const User: UserConstructor = function(username: string) {
this.username = username
}
User.prototype.age = 57
The compiler complains since the value of this
is unknown and the call signatures don't seem to match.
After doing some research, I was able to come up with a version that works but I don't really like it:
interface ICUser {
username: string;
age: number;
}
function ConstructedUser(this:ICUser, username: string) {
this.username = username;
}
ConstructedUser.prototype.dateOfBirth = "Freb"
Here's what I don't like about solution nr. 2:
I wasn't able to find good resources on how to type constructor functions and hoped someone might be able to help.
It looks like the answer is that you can't do this without type assertions (e.g. as any
), because you aren't supposed to write constructor functions in Typescript. This GitHub issue suggests allowing it, and the suggestion was marked as "declined" and closed:
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.
The proper way to write your code in Typescript is using the class
syntax to declare a class. If it's needed for compatibility with older browsers, you can force tsc
to convert your class declaration into a constructor function during compilation, by setting the target language level to ES3 or ES5.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With