Skip to content
This repository has been archived by the owner on Apr 2, 2020. It is now read-only.

How do you extend prototypes as suggested in globalBootStrap()? #9

Closed
staff0rd opened this issue Mar 7, 2016 · 4 comments
Closed

Comments

@staff0rd
Copy link

staff0rd commented Mar 7, 2016

This suggests that interfaces can't be extended.

@MarkoSulamagi
Copy link
Owner

I can comment on this tomorrow.

@MarkoSulamagi
Copy link
Owner

Although, Typescript classes and inheritance are compiled to JavaScript prototypes, you can't easily extend Screeps' object prototypes, because interface doesn't allow it.

  1. One possibility is to clone the "screeps-typescript-declarations" module and add your own method description to the interfaces. Then you can extend the functionality the same way as you would using vanilla Javascript.
// Declaration
interface creep {
  prototype: Creep;

  ..
  foo(): void;
}

// Implementation
Creep.prototype.foo = function() { console.log("bar"); } `

Drawback for this is that if "screeps-typescript-declarations" project is updated then you would have to merge the changes manually to your project. Which is quite inconvenient.

  1. For my own project, I don't extend Screeps object prototypes at all and instead, wrap them in seperate classes.

For example:

interface SuperCreepInterface {
  creep: Creep;
  setCreep(creep: Creep): void;
  foo(): void;
}

class SuperCreep implements SuperCreepInterface {
  creep: Creep = null;

  public function setCreep(creep: Creep) {
    this.creep = creep;
  }

  public function foo() {
    console.log(this.creep);
  }
}

Sad part for this solution is that it's not very pro JavaScript. JS is popular by its prototypes and unfortunately we're going more "Java" like. It's not supposed to be like that.

  1. If you have a better solution then I'm all ears. I'd like to know how to solve it also.

I linked this issue to GitHub page and also asked opinion from some people in IRC.
Thanks for bringing it up.

@NhanHo
Copy link

NhanHo commented Mar 8, 2016

//prototype.d.ts
interface Creep {
    foo():void;
}
//prototype.ts
Creep.prototype.foo = function(){};
//foo.ts
let c: Creep = Game.creeps["foo"];
c.foo(); //This will compile without error

//Just for good measure, we can see that this will also compile without error
c.attack(Game.creeps["bar"]); 

It seems like TS compiler knows to merge different ambient module, so all we have to do is declaring an interface Creep in a .d.ts file, containing all the new function that we're extending the prototype with

@MarkoSulamagi
Copy link
Owner

This seems to work well, NhanHo. Thanks.

I'll close this issue. Feel free to reopen it if there's something to add.

# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants