Repository: sequelize/sequelize
File: packages/core/src/model-typescript.ts (TypeScript)

Code before:
   * If not found, returns null or throws an error if {@link FindOptions.rejectOnEmpty} is set.
   *
   * @param      param The value of the desired instance's primary key.
   * @param      [options] find options
   * @returns
   */
  static async findByPk<M extends Model>(
    this: ModelStatic<M>,
    param: number | bigint | string | Buffer | object,
    options?: FindByPkOptions<Attributes<M>>,
  ): Promise<ModelTypeScript | null> {
    // return Promise resolved with null if no arguments are passed
    if (param == null) {
      return null;
    }

    options = cloneDeep(options) ?? {};

    const hasCompositeKey = Object.keys(this.primaryKeys).length > 1;
    if (hasCompositeKey && !isPlainObject(param)) {
      throw new TypeError(
        `Model ${this.name} has a composite primary key. Please pass all primary keys in an object like { pk1: value1, pk2: value2 }`,
      );
    } else if (hasCompositeKey && isPlainObject(param)) {
      const params = param as Record<string, unknown>;
      const where: WhereOptions = {};
      for (const pkColumn of Object.values(this.primaryKeys).map(pk => pk.columnName)) {
        if (params[pkColumn] !== undefined) {
          where[pkColumn] = params[pkColumn];
        }
      }

      if (Object.keys(this.primaryKeys).length !== Object.keys(where).length) {
        throw new TypeError('Primary key mismatch. Please pass all primary keys');
      }

      options.where = where;
    } else if (
      typeof param === 'number' ||
      typeof param === 'bigint' ||
      typeof param === 'string' ||
      Buffer.isBuffer(param)
    ) {
      options.where = {
        // @ts-expect-error -- attribute could be null
        [this.primaryKeyAttribute]: param,
      };
    } else {
      throw new TypeError(`Argument passed to findByPk is invalid: ${param}`);
    }


Review comment (suggestion):
I believe we prefer to use `Object.create(null)` instead of `{}`

Code after:
   *
   * @param      param The value of the desired instance's primary key.
   * @param      [options] find options
   * @returns
   */
  static async findByPk<M extends Model>(
    this: ModelStatic<M>,
    param: number | bigint | string | Buffer | object,
    options?: FindByPkOptions<Attributes<M>>,
  ): Promise<Model | null> {
    // return Promise resolved with null if no arguments are passed
    if (param == null) {
      return null;
    }

    options = cloneDeep(options) ?? {};
    const where = Object.create(null);

    const hasCompositeKey = Object.keys(this.primaryKeys).length > 1;
    if (hasCompositeKey && !isPlainObject(param)) {
      throw new TypeError(
        `Model ${this.name} has a composite primary key. Please pass all primary keys in an object like { pk1: value1, pk2: value2 }`,
      );
    } else if (hasCompositeKey && isPlainObject(param)) {
      const params = param as Record<string, unknown>;
      for (const pkColumn of Object.values(this.primaryKeys).map(pk => pk.columnName)) {
        if (params[pkColumn] !== undefined) {
          where[pkColumn] = params[pkColumn];
        }
      }

      if (Object.keys(this.primaryKeys).length !== Object.keys(where).length) {
        throw new TypeError('Primary key mismatch. Please pass all primary keys');
      }
    } else if (
      typeof param === 'number' ||
      typeof param === 'bigint' ||
      typeof param === 'string' ||
      Buffer.isBuffer(param)
    ) {
      const pk = this.primaryKeyAttribute;
      if (pk !== null) {
        where[pk] = param;
      }
    } else {
      throw new TypeError(`Argument passed to findByPk is invalid: ${param}`);
    }

    options.where = where;

    // Bypass a possible overloaded findOne