1

I'm using a project mixed with both javascript and typescript. Declaration files for modules can be easily created using - declare module. But how do I create a declaration for a javascript file in my current folder?

For ex -

player.js -
var Player = function() {};
Player.prototype.validate = function() {};

How do I create declaration so that I can extend it in typescript. I want to do something like this -

player.ts -
let Player = require('./player');
Player.prototype.login = function() {
    this.validate();
}

I know the above code will work by setting Player type as any but I won't be able to type check.

3 Answers 3

1

TypeScript does not understand the prototypal syntax / constructor functions: there will be no intellisense. It prefers ES6 classes.

The JavaScript Player constructor function is equivalent to this TypeScript class definition:

// -- player.d.ts --
declare class Player {
  validate(): void;
}

Then, to add a method to the Player class, there's a couple of options:

  1. The more TypeScript idiomatic ways: class inheritance or class composition
  2. A compromise to keep using the prototypal syntax in TypeScript and still get the intellisense: facade interface

Code examples:

// -- authenticated-player.ts --
import { Player } from './player'; 

// Option #1a: class inheritance
class AuthenticablePlayer extends Player {
  login() {
    this.validate();
  }
}

const p1a = new AuthenticablePlayer();
p1a.login();

// Option #1b: class composition + delegation
class AuthenticablePlayerB {
  private player = new Player(); 

  login() {
    this.validate();
  }

  validate() {
    this.player.validate();
  }
}

const p1b = new AuthenticablePlayerB();
p1b.login();

--

// Option #2: prototype extension + facade interface + type assertion
const Player: any = require('./player');

Player.prototype.login = function() {
  this.validate();
}

interface IPlayer {
  login(): void;
  validate(): void;
}

function createPlayer(): IPlayer {
  return new Player();
}

const p2 = createPlayer();
p2.login();
Sign up to request clarification or add additional context in comments.

2 Comments

For more details on the difference between declare class and interface, see stackoverflow.com/a/14348084/1704166
was hoping there was a way to add to current class without extending it. But I guess I'll have to extend.
0

You can create interface in your TypeScript file and set that as the type for Player.

interface IPlayer {
  validate();
}

let Player: IPlayer = require('./player');

Player.prototype.login = function() {
    this.validate();
}

1 Comment

error TS2339: Property 'prototype' does not exist on type 'IUser'.
0

To expand on Sabbir's answer here (not enough room in comments)

interface IPlayer { 
  validate(): void
  login():void
}

old js code

var Player = function () { }
Player.prototype.validate = function() {}

using in ts project

// import / require here, left out for brevity
Player.prototype.login = function() {
    this.validate()
}

create a player - login and validate now have auto completion

let p: IPlayer = new Player()
p.login()
p.validate()

3 Comments

but auto completion won't work inside the player function
I don't know your exact project use case but personally I would prefer to create a Typescript Class and copy the JS methods over. Then you will get full code completion. Check the edit
It's a really big class and I don't want to mix javascript and typescript code.

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.