1

I want to create a function that can be invoked with the new keyword. However, none of my implementation works and Typescript keeps showing me errors.

Below is my code. You can see it on the Typescript Playground too

type Account = {
  username: string
  password: string
}

type AccountConstructor = {
  new (username: string, password: string): Account
  (username: string, password: string): Account
}

// const Account: AccountConstructor = function (username: string, password: string) {
//   return {username, password}
// }

// Type '(username: string, password: string) => { username: string; password: string; }' is not assignable to type 'AccountConstructor'.
// Type '(username: string, password: string) => { username: string; password: string; }' provides no match for the signature 'new (username: string, password: string): Account'.
const Account: AccountConstructor = function(username: string, password: string) {
  return {
    username,
    password
  }
}

// Type 'typeof Account' is not assignable to type 'AccountConstructor'.
// Type 'typeof Account' provides no match for the signature '(username: string, password: string): Account'.
const Account: AccountConstructor = class {
  constructor(public username: string, public password: string) {}
}

new Account('username', 'password')

How to implement the Construct Signature correctly that the function could be invoked using the new keyword?

9
  • How is the class approach not working? could you elaborate what error do you see when doing " new AccountClass ('username', 'password') " ? also i can't see you doing that in the code above. Commented Oct 16, 2022 at 4:56
  • 1
    Why not just write class Account { ... }? Commented Oct 16, 2022 at 6:53
  • @root My mistake. The AccountClass class is created just to test if the normal class works fine. It does not relate to the question. I have updated the code, so we can focus on the errors thrown by the Construct Signature, which is the AccountConstructor type Commented Oct 16, 2022 at 6:53
  • @kaya3 class Account { ... } is okay but I want to use the new keyword to invoke a function just like I can do with JavaScript. I discovered construct signature, but don't know how to use it. The official doc doesn't show how to implement it too. Commented Oct 16, 2022 at 6:56
  • 1
    The official documentation doesn't show how to do it because you aren't supposed to do it - that is the old way of creating "classes", from before Javascript had the class syntax. Commented Oct 16, 2022 at 6:57

1 Answer 1

4

In Typescript code you should write classes, not constructor functions; constructor functions are the old way of implementing "classes" in Javascript, from before the class syntax was added. This pattern may still be used in older libraries, or libraries compiled to ES5 or earlier for compatibility purposes. (If you need this compatibility, set your target to ES5, and your Typescript class declarations will be automatically converted when you compile.)

Constructor signatures are primarily meant to be used when defining types in a .d.ts file for a library that is not written in Typescript. However, you can also use them for passing classes around like this:

type Foo = {x: string}

type FooConstructor = new (x: string) => Foo

class FooClass {
    constructor(public x: string) {}
}

const fooConstructor: FooConstructor = FooClass;

Playground Link

The difference between this and your example using a class, is that your interface requires both a construct signature and a call signature, but classes do not have call signatures.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.