Определите параметры типа с членами stati c - PullRequest
1 голос
/ 04 августа 2020

Я пытаюсь создать несколько служебных классов для моей веб-службы RESTful, чтобы уменьшить количество шаблонного кода.

Вот упрощенный пример моих служебных классов:

class Model {
    public static async findAll(options: any) {
        return Promise.resolve([]);
    }
}

class Service<M> {
    public model: M;
    // this will fix the following problem with "findAll". But we can't access "User" model members in "UsersService"
    // public model: typeof Model;

    constructor(options: { model: any }) {
        this.model = options.model;
    }

    public async find(params?: any): Promise<any> {
        return this.model.findAll(params); // error: Property 'findAll' does not exist on type 'M'
    }
}

Пример использования:

class User extends Model {
    firstName: string;
    lastName: string;

    constructor(options: any) {
        super();

        this.firstName = options.firstName;
        this.lastName = options.lastName;
    }
}

class UsersService extends Service<typeof User> {
    constructor() {
        super({ model: User });
    }

    public async customMethod() {
        const users = this.find({});

        const newUser = new this.model({ firstName: 'foo', lastName: 'bar' });

        newUser.firstName // ok
        newUser.lastName // ok
    }
}

Я не могу понять, как мне определить параметры типа для класса «Service», поэтому я могу получить доступ к «findAll» в классе «Service», а также получить доступ к «firstName» и « lastName »в« UsersService »?

Если я определяю параметр типа как« M extends Model », я все равно не могу получить доступ к членам stati c.

Пример REPL

1 Ответ

0 голосов
/ 05 августа 2020

Вы можете сделать это:

class Model {
    public static async findAll(options: any) {
        return Promise.resolve([]);
    }

    public f(): string { return ''}
}

type AnyConstructor = new (...args: unknown[]) => unknown;
type StaticProperties<T extends AnyConstructor> = Pick<T, keyof T>;

class Service<M extends StaticProperties<typeof Model>> {
    public model: M;

    constructor(options: { model: M }) {
        this.model = options.model;
    }

    public async find(params?: any): Promise<any> {
        return this.model.findAll(params); // error: Property 'findAll' does not exist on type 'M'
    }
}

class User extends Model {
    firstName: string;
    lastName: string;

    constructor(options: any) {
        super();

        this.firstName = options.firstName;
        this.lastName = options.lastName;
    }
}

class UsersService extends Service<typeof User> {
    constructor() {
        super({ model: User });
    }

    public async customMethod() {
        const users = this.find({});

        const newUser = new this.model({ firstName: 'foo', lastName: 'bar' });

        newUser.firstName // ok
        newUser.lastName // ok
    }
}

На данный момент создание интерфейса для свойств c stati - это своего рода беспорядок. Надеюсь, это предложение может упростить задачу

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...