Search code examples
expresstypeorm

ReferenceError: Cannot initialise user (entity) before initialization


I've defined 3 entities - user, company and companyuser in my express app using typeorm. On compilation, I get the following error:

ReferenceError: Cannot access 'User' before initialization
    at file:///C:/Users/Yu/Desktop/Projects/keytest/keytest-backend/models/CompanyUser.ts:23:9

Why is this happening, and how can I fix this?

The error comes from the ManyToOne decorator for the user field in the CompanyUser entity, as commenting out that line gets rid of the error

User entity:

@Entity()
export class User extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  firstName: string;

  @Column()
  lastName: string;

  @Column()
  email: string;

  @CreateDateColumn()
  createdAt: Date;

  @OneToMany(() => CompanyUser, companyUser => companyUser.user, { onDelete: 'CASCADE' })
  companyUsers: CompanyUser[];
}

Company entity:

export class Company extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;

  @CreateDateColumn()
  createdAt: Date;

  @Column()
  name: string;

  @OneToMany(() => CompanyUser, companyUser => companyUser.company)
  companyUsers: CompanyUser[];
}

CompanyUser entity:

export class CompanyUser extends BaseEntity {
  @PrimaryGeneratedColumn()
  id: number;
  
  @Column({ default: false })
  isVerified: boolean;

  @Column({ default: false })
  isAdmin: boolean;

  @Column({ default: false })
  isDisabled: boolean;
  
  @CreateDateColumn()
  createdAt: Date;
  
  @ManyToOne(() => User, user => user.companyUsers)
  user: User;

  @ManyToOne(() => Company, company => company.companyUsers)
  company: Company;
}

The datasource:

const AppDataSource = new DataSource({
    type: "postgres",
    host: process.env.BACKEND_URL,
    port: process.env.DB_PORT as unknown as number,
    username: process.env.DB_USERNAME,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    entities: [User, Company, CompanyUser],
    synchronize: true,
    logging: true,
  });

Solution

  • It seems there was a circular dependency between my User and CompanyUser entities, hence the error. To fix it, I added a relation wrapper.

    According to the typeorm docs:

    Doing this prevents the type of the property from being saved in the transpiled code in the property metadata, preventing circular dependency issues.

    Just remember to not use the Relation wrapper on non-relation column types.

    So the CompanyUser entity becomes:

    @Entity()
    export class CompanyUser extends BaseEntity {
      @PrimaryGeneratedColumn()
      id: number;
      
      @Column({ default: false })
      isVerified: boolean;
    
      @Column({ default: false })
      isAdmin: boolean;
    
      @Column({ default: false })
      isDisabled: boolean;
      
      @CreateDateColumn()
      createdAt: Date;
      
      @ManyToOne(() => User, (user) => user.companyUsers)
      user: Relation<User>;
    
      @ManyToOne(() => Company, (company) => company.companyUsers)
      company: Company;
    }