1

Ive been creating my classes like this:

interface ICar {
  wheels: number;
  model: string;
  drive?: () => void;
}

const Car = function(c: ICar) {
  this.wheels = c.wheels
  this.model = c.model
  this.drive = function() {
    console.log(this.model) // <-- this doesnt autocomplete when typing `this.`
  }
}

A small problem im having is that referencing this within the class doesn't show autocompletion which is making me make some small mistakes in my much larger classes.

I instead can make a class like this:

interface ICar {
  wheels: number;
  model: string;
  drive: () => void;
}

class Car {
  wheels: number;
  model: string;
  drive: () => void;

  constructor(obj: ICar) {
    this.wheels = obj.wheels;
    this.model = obj.model;
    this.drive = function() {
      console.log(this.model) // this provides autocompletion and type checking
    }
  }
}

However, with this, I feel like there is a lot of repetition of code. I dont like how I define the interface ICar and then i have to essentially repeat the code within the class.

I thought using implements would fix it eg: class Car implements ICar but that doesnt work either.

Is there something im missing or am I doing this wrong?

4
  • Sounds like your editor doesn't understand old-style Javascript prototypes. This is dependent on your code editor, so you'll want to mention what you're using Commented Sep 4, 2022 at 20:17
  • Looks like you are trying to use inheritance, but you have not actually done that. Is this what you are looking for? Commented Sep 4, 2022 at 20:32
  • I don't think that is dependent on your code editor - it's the Typescript language server. Typescript fundamentally does not like old-style Javascript constructor functions, you should write a class instead. You are supposed to use the class syntax to create a class; the thing about code repetition is just that you don't need to declare your interface at all, the class can be used like an interface because Typescript uses structural types, not nominal types. Commented Sep 4, 2022 at 20:33
  • 2
    Also, function()( { ... } with this inside almost certainly is not what you actually want here. this doesn't refer to the this from the class. If you use an arrow function like () => { ... } then you can use this from the outer scope. It's also kind of suspect that your constructor's parameter is something of the same type ICar that you are (apparently) trying to construct; if you already have an argument of type ICar to pass to the constructor then what do you need to call the constructor for? Commented Sep 4, 2022 at 20:35

2 Answers 2

1

You can actually specify the type of "this" since Typescript 2.0. That should help you get the correct type for the "this" keyword.

Using your example:

interface ICar {
  wheels: number;
  model: string;
  drive?: () => void;
}

const Car = function(this: ICar, c: ICar) {
  // Now the type of "this" should be `ICar`
  this.wheels = c.wheels
  this.model = c.model
  this.drive = function() {
    console.log(this.model)
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

You're editor isn't up to much if it can't spot the class members.

You may want to use an abstract class and extend it, also setting the access scope will auto set the member for you:

abstract class Car {
    abstract wheels: number
    abstract model: string;
    abstract drive(): void;
}

class MyCar extends Car {
    constructor(public wheels: number, public model: string) {
        super()
    }
    drive() { }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.