1

I want to create a class type for classes with certain properties. E.g.:

class Cat {
  name = 'cat';
}

class Dog {
  name = 'dog';
}

type Animal = ???;

function foo(AnimalClass: Animal) {
  console.log((new AnimalClass()).name);
}

I want doSomething to accept any class that has a string name property. The only way I could do this is:

class _Animal {
  name: string;
}

type Animal = typeof _Animal;

Is there a way to do this without defining a new JS class? I just want the type.

1
  • Interfaces aren't compiled to javascript, and ideally to be used for intellisense. That's the best option. A drawback is that on creation, you have to explicitly define all properties. Commented Aug 22, 2020 at 7:51

2 Answers 2

3

You can describe constructor using new expression:

type AnimalContructor = new () => { name: string };

function foo(AnimalClass: AnimalContructor) {
  console.log((new AnimalClass()).name);
}

Playground


Other option is defining union of constructors:

type AnimalContructor = typeof Cat | typeof Dog;

Playground

Sign up to request clarification or add additional context in comments.

3 Comments

With the new () => {} syntax, is it possible to use extends? E.g. if Dog and Cat both extend a third-party library class, I want Animal to extend the same class. I tried something like type AnimalConstructor = new () => { name: string; prototype: Foo.prototype }; but that didn't work
Yes, you can use intersection for this type AnimalContructor = new () => { name: string } & Foo; typescriptlang.org/play?#code/…
Nice, Five Answers! with respect 🌹
0

What you can do is to use generics here. I create a type that I make this type to be only assignable to object with name property as a string, and then I add a generic type that extends Animal type. This way you don't have to create a new class for Animal.

class Cat {
  name = "cat";
  age = 2;
}

class Dog {
  name = 'dog';
}

class Car {
  brand = "Audi";
}

type Animal = {name: string};

function doSomething<T extends Animal>(animal: T) {
}

doSomething(new Dog());
doSomething(new Cat());
doSomething(new Car()); // typescript error car is missing name

And if you would like to make Animal type extend another class you can use intersection

class Cat {
  name = "cat";
  age = 2;
}

class Information {
  year = 2020;
}
class Dog extends Information {
  name = 'dog';
}

type Animal = { name: string } & Information;

function doSomething<T extends Animal>(animal: T) {
}

doSomething(new Dog());
doSomething(new Cat()); // typescript error cat is missing year

Comments

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.