Passiday
Passiday

Reputation: 8075

TypeScript: defining a type that specifies a new-able function

I am looking for a way how to replicate the following JavaScript functionality in TypeScript:

class Tree {
  constructor(name) {
    this.name = name;
    this.type = 'unspecified';
  }
  grow() {
    console.log(`${this.name} (${this.type}): growing.`);
  }
}

class Pine extends Tree {
  constructor(name) {
    super(name);
    this.type = 'pine';
  }
  somethinPiney() {
    return true;
  }
}

function treeMaker(treeType, name) {
  return new treeType(name);
}

const t = new Tree('Noname');
const p = new Pine('Backyard');
const m = treeMaker(Pine, 'Seaside');

t.grow();
p.grow();
m.grow();

console.log(m instanceof Pine); // true
console.log(m instanceof Tree); // true
console.log(m instanceof Date); // false

More specifically, the treeType parameter type in the treeMaker function. It represents a new-able function. What syntax is used to describe such type? And how can I specify that I am interested only in Tree or a class that extends Tree?

Upvotes: 0

Views: 99

Answers (1)

fjc
fjc

Reputation: 5825

Here you go with a TypeScript translation that's as close as possible to your JavaScript code:

class Tree {
  constructor(private name: string, private type = 'unspecified') {
  }

  grow() {
    console.log(`${this.name} (${this.type}): growing.`);
  }
}

class Pine extends Tree {
  constructor(name: string) {
    super(name, 'pine');
  }

  somethinPiney() {
    return true;
  }
}

function treeMaker<T extends Tree>(treeType: new (name: string) => T, name: string): T {
  return new treeType(name);
}

const t = new Tree('Noname');
const p = new Pine('Backyard');
const m = treeMaker(Pine, 'Seaside');

t.grow();
p.grow();
m.grow();

console.log(m instanceof Pine); // true
console.log(m instanceof Tree); // true
console.log(m instanceof Date); // false

Upvotes: 2

Related Questions