Ryan McClure
Ryan McClure

Reputation: 1233

Defining static methods outside of typescript class

I have an api that is built using Sequelize. It is structured such that there are base models defined in one place, and their respective class methods are defined in another place. This was done so the models could be exported on their own, or built to contain all extra class methods.

For example, here's a Thread model:

// ./models/thread.ts
class Thread extends Model<Thread> {
    id: string;
    public static createOne: () => void;
    ...
}

The Thread model is eventually exported along with all other models:

// ./models/index.ts
export { default as Thread } from './thread';
export { default as Message } from './message';
...
// ./index.ts
import * as models from './models';

export interface IModels {
    Thread: models.Thread,
    ...
}

export { models }

And the following would be the function defined to add class methods to the Thread. This is passed the models object, which was done in an effort to avoid circular dependencies when writing methods that relied on other models:

const addThreadClassMethods = (models: IModels) => {
    // Throws "Property 'createOne' is a static member of type 'Thread'"
    models.Thread.createOne = () => { ... }
}

This works functionally, but typescript throws an error saying Property 'createOne' is a static member of type 'Thread'. At first this made sense to me, but I then realized that I can do the following without typescript throwing an error:

import Thread from './models/thread';

// No errors
Thread.createOne = () => { ... }

In the first case, I'm modifying the property of a class that is a member of a function argument, while in the latter I'm modifying the property on that class directly. Isn't this effectively the same thing?

Upvotes: 0

Views: 452

Answers (1)

TND
TND

Reputation: 74

Typescript has variable name scope and type name scope. Your IModel have property named 'Thread' with type named 'Thread'.

When you declare any class, typescript make 2 things for you. 1: variable of your class's name map to constructor function. 2: type of your class's name map to instance type of your class(not your class)

to fix your issue change IModel to

{
    Thread: typeof models.Thread
}

Upvotes: 1

Related Questions