4

I'm moving from js to typescript and i have some challenges.

I need to convert a constructor function to the equivalent of typescript.

The function in js is like so:

export default function(address) {
  var self = this ;
  self.address = address;
  
  self.init = function(){
    //some code
  }

  self.onClick = function() {
   // some code
  }
}

I tried to convert it but it complains in this keyword. (missing anotation)

const Address: (address: string) => void = function (address: string) {
   this.address = address;
 }

Address.prototype.init = function() {
  // some code here
}

export default Address

and I'm planning to call it inside react component, from another file, like so: new (Address as any)(address_here));

I'm having the issue with the this so I haven't checked if the prototype function works too.

Nick Decroos
  • 153
  • 1
  • 8
Theo Itzaris
  • 4,321
  • 3
  • 37
  • 68
  • Its not the full code, just a fragment. Currently i dont return anything, that s why i added void. – Theo Itzaris Mar 02 '20 at 10:53
  • 2
    You can follow this also if you are keen on using constructor function - https://stackoverflow.com/questions/43623461/new-expression-whose-target-lacks-a-construct-signature-in-typescript#answer-51622913 – Arpitha Chandrashekara Mar 02 '20 at 11:13

2 Answers2

0

You can create a class and add methods to it.

Note: All methods in TS Class goes to prototype and properties to object. You can even define a static method which is similar to adding method to function in ES5

export default class SetAddress {
  constructor( public readonly address: string ) {}

  public init(): void {}

  public onClick(event: HTMLEventAction): void {}
}

You can even test at TS PlayGround. You will have to set the target version to ES5

enter image description here

Rajesh
  • 24,354
  • 5
  • 48
  • 79
  • Nice @Rajesh, thank you. I didnt know that there is a playground. So, it seems that i have to do a Class, if i understand correctly. – Theo Itzaris Mar 02 '20 at 11:06
  • @TheoItzaris Correct. In Object Oriented system there is no constructor without Class. You have classes or primitive datatypes – Rajesh Mar 02 '20 at 11:07
  • 3
    This is wrong! JavaScript classes and constructor functions are two distinct although similar features of ECMAScript. See https://stackoverflow.com/q/36419713/2779871 – Jules Sam. Randolph May 02 '21 at 18:24
0

Well you can use class declaration syntax:

export default class Address{
    constructor({address}:Object){
       this.address : String = address;
    }

    init():void{ // or your type of return
      // some code
    }

    onClick():void{ // or your type of return
      // some code
    }
}
Jai
  • 74,255
  • 12
  • 74
  • 103
  • An opinionated comment but constructor accepting an object defeats the purpose of having object – Rajesh Mar 02 '20 at 11:04
  • So does that mean it should be anything other than object? – Jai Mar 02 '20 at 11:11
  • @Rajesh The copy constructor pattern uses exactly that pattern and in javascript it's quite comment to create a class instance by passing in an object with configuration data or properties rather then adding dozens of parameters to the constructor. – Andreas Dolk Mar 02 '20 at 11:12
  • My point is, if you have a constructor, you should expect individual value. Like `address( buildingName: string, area: string, city: string, country: string) {}` instead. Passing an object means you can pass anything – Rajesh Mar 02 '20 at 11:13
  • @Andreas_D Accepted. Even I use them but still not comfortable in using them. Point is, using `Partial` doesn't specify what is missing. So you go back to defaults. Yes its a commonly used way but only because we add a lot of properties to a type and using traditional constructor becomes tedious. But I still prefer using traditional constructors when it comes to smaller classes. – Rajesh Mar 02 '20 at 11:17
  • @Rajesh what i suggested is destructuring the passed properties of object. That way you can extract multiple properties. – Jai Mar 02 '20 at 11:17
  • @Andreas_D an example to support my comment, if you use a proper IDE, you can hover on and get definition. When you use this pattern, you loose this feature. – Rajesh Mar 02 '20 at 11:18
  • @Rajesh What we shouldn't use, if that was your point, is a parameter that is typed `Object` (or `object` or `any`) but define a proper type. But in this answer, I considered it as a placeholder, a dummy for the proper type that contains the `address` field. – Andreas Dolk Mar 02 '20 at 11:19
  • @Andreas_D Agreed. But still using `Partial` being a proper type can be misleading. And it maybe my POV only. Hence I started with *an opinionated comment*. My point is passing an object to a constructor is like *aabra ka dabra in magic*... It'll get things done but you have no idea what or how. And usually there are assumptions under the hood that comes to bite you – Rajesh Mar 02 '20 at 11:24
  • @Rajesh I know this comment is old, but I'll reply for any future reader's sake. An objects is "objectively" better than a whole list of arguments, simply because you can easily update arguments that are now optional. For example, mobile phones are now common, whereas home phones are uncommon. If you have `details(name : string, home_phone : number, mobile : number)`, now you have you to pass in `null`, whereas you can simply omit values in an object. And it's not "magic", `you have no idea what or how` which I don't see how it doesn't apply to arguments too? Also a 20 argument function is bad – A. L Sep 29 '22 at 06:08
  • @A.L *Also a 20 argument function is bad* Cant agree more but if there is a function that needs 20 args, it can surely be separated into smaller ones. Point with strict type is to know what needs to be sent. Yes, same can be achieved with object as well but I prefer having separate variables instead. Also, this is an opinionated comment. We both are correct in our own right, its just we prefer different styles – Rajesh Sep 29 '22 at 07:18