2

I have the following class that I would like to access in a different file:

export class Person {

    constructor() {}

    static getDatabaseId(): string {
        return '...';
    }
}

It's injected and not actually imported. I want to make clear that it is a constructor function and that it can create new instances of type Person. This is what I tried:

let PersonConstructor: {new(): Person};

// inject Person constructor function
beforeEach(inject((_Person_) => {
    PersonConstructor = _Person_;
}));

// create a new instance but also access the static variables
const p: Person = new PersonConstructor();
PersonConstructor.getDatabaseId(); // "property does not exist"

The compiler doesn't complain about instantiating new instances from Person anymore but of course it also doesn't know of Person's static variables now since they are missing on the newly declared type.

How can this be typed correctly?

4
  • what is "const Person: {new(): Person)" for? Commented May 17, 2019 at 12:37
  • I renamed it so It's clearer: PersonConstructor is a constructor function that creates instances of type Person. Commented May 17, 2019 at 12:46
  • An instance member belongs to the class not the object, which means that whenever you create a new instance of Person it won't have static members, in this case getDatabaseId() method. Commented May 17, 2019 at 12:57
  • I updated my code example: The constructor function is injected and assigned to a local variable. So I have to express somehow what is getting injected. Commented May 17, 2019 at 13:01

2 Answers 2

3

I'm not sure what is the final goal of your code. As of TypeScript doc one possible usage of syntax you tring to achive is to modify static member of the class and create new instances with new static members.

If you are going to do that correct code will look like

let PersonConstructor: typeof Person = Person;

// create a new instance but also access the static variables
const p: Person = new PersonConstructor();
PersonConstructor.getDatabaseId(); // Also OK and you my change it. Original Person will not get it changed.
Sign up to request clarification or add additional context in comments.

Comments

2

You can use the constructor signature method but you will need to add any other members you need to access.

import {Person} from './Person';

let PersonConstructor: {
    new(): Person
    getDatabaseId(): string
} = Person;

// create a new instance but also access the static variables
const p: Person = new PersonConstructor();
PersonConstructor.getDatabaseId(); // "property does not exist"

Alternately, you could just use typeof Person if you want to use the exact same type as the Person (constructor signature and all statics):

import {Person} from './Person';

let PersonConstructor: typeof Person = Person;

// create a new instance but also access the static variables
const p: Person = new PersonConstructor();
PersonConstructor.getDatabaseId(); // "property does not exist"

1 Comment

The second code example was what I was looking for, thank you!

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.