0

I have one class:

export class DataAccess {
  tableName: string;
  constructor({ tableName }: { tableName: string }) {
    this.tableName = tableName;
  }
  async getWhere(where: any, { single = false } = {}) {
    const options: { limit?: number } = {};
    if (single) {
      options.limit = 1;
    }
    const results = await someDBobj[this.tableName].find(where, options);
    if (!single) {
      return results;
    }
    return results.length ? results[0] : null;
  }
}

And a subclass:

import { DataAccess } from "./data-access";

type UsersTable = {
  id: string;
  email: string;
  password: string;
  createdAt: Date;
};

export default class Users extends DataAccess {
  columns: { [P in keyof UsersTable]: string };
  constructor() {
    super({
      tableName: "users"
    });
    this.columns = {
      id: "id",
      email: "email",
      password: "password",
      createdAt: "createdAt"
    };
  }
}

And using the Users class:

await users.getWhere(
  {
    email: user,
    password
  },
  {
    single: true
  }
);

How can I set the Type of where: any in the parent DataAccess Class, so it knows that its the Users subclass that's called it?

2 Answers 2

1

You can use generic class


export class DataAccess<T> {
  columns: { [P in keyof T]: string };
  tableName: string;
  constructor({ tableName }: { tableName: string }) {
    this.tableName = tableName;
  }
  async getWhere(where: Partial<T>, { single = false } = {}) {
    const options: { limit?: number } = {};
    if (single) {
      options.limit = 1;
    }
    const results = await someDBobj[this.tableName].find(where, options);
    if (!single) {
      return results;
    }
    return results.length ? results[0] : null;
  }
}

import { DataAccess } from "./data-access";

type UsersTable = {
  id: string;
  email: string;
  password: string;
  createdAt: Date;
};

export default class Users extends DataAccess<UsersTable > {
  constructor() {
    super({
      tableName: "users"
    });
    this.columns = {
      id: "id",
      email: "email",
      password: "password",
      createdAt: "createdAt"
    };
  }
}

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

1 Comment

async getWhere(where: Partial<T>, { single = false } = {}) {, I think...
0

It looks like you are only extending the class to get specialisation of the data shape. In that case, you could do something like this:

class DataAccess<T> {
  columns: { [P in keyof T]: string };
  tableName: string;
  constructor({ tableName, columns }: { tableName: string, columns: { [P in keyof T]: string } }) {
    this.tableName = tableName;
    this.columns = columns;
  }
  async getWhere(where: Partial<T>, { single = false } = {}) {
    const options: { limit?: number } = {};
    if (single) {
      options.limit = 1;
    }
    const results = await someDBobj[this.tableName].find(where, options);
    if (!single) {
      return results;
    }
    return results.length ? results[0] : null;
  }
}

type UsersTable = {
  id: string;
  email: string;
  password: string;
  createdAt: Date;
};

const user = new DataAccess<UsersTable>({tableName: ""users", columns: {
  id: "id",
  email: "email",
  password: "password",
  createdAt: "createdAt"
};})

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.