typeORM定义entity为何会报错:(alias) PrimaryGeneratedColumn(): import PrimaryGeneratedColumn?

使用typeORM的时候:
比如:定义了一个Entity:

import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'

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

  @Column()
  firstName: string

  @Column()
  lastName: string 

  @Column()
  age: number
}

有2个报错:
image.png
image.png

1、

作为表达式调用时,无法解析属性修饰器的签名。
  类型“undefined”的参数不能赋给类型“Object”的参数。ts(1240)
(alias) PrimaryGeneratedColumn(): PropertyDecorator (+5 overloads)
import PrimaryGeneratedColumn
Column decorator is used to mark a specific class property as a table column.

2、

属性“firstName”没有初始化表达式,且未在构造函数中明确赋值。ts(2564)
(property) User.firstName: string

请问是需要如何进行修复呢?还是说这个本来就是这样定义的?


更新:
我这边是有添加AI bot回复的信息的,但是还是有提示报错信息:

{
   "compilerOptions": {
      ...
         "target": "es5",
      "module": "commonjs",
      "moduleResolution": "node",
      "outDir": "./build",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "esModuleInterop": true,
      "sourceMap": true

image.png

===

编辑:1

package.json

{
   "name": "electron-test-05-typeorm",
   "version": "1.0.0",
   "description": "An Electron application with React and TypeScript",
   "main": "./out/main/index.js",
   "author": "example.com",
   "homepage": "https://electron-vite.org",
   "scripts": {
      "format": "prettier --write .",
      "lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
      "typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false",
      "typecheck:web": "tsc --noEmit -p tsconfig.web.json --composite false",
      "typecheck": "npm run typecheck:node && npm run typecheck:web",
      "start": "ts-node src/index.ts",
      "dev": "electron-vite dev",
      "build": "npm run typecheck && electron-vite build",
      "postinstall": "electron-builder install-app-deps",
      "build:unpack": "npm run build && electron-builder --dir",
      "build:win": "npm run build && electron-builder --win",
      "build:mac": "electron-vite build && electron-builder --mac",
      "build:linux": "electron-vite build && electron-builder --linux",
      "typeorm": "typeorm-ts-node-commonjs",
      "rebuild": "electron-rebuild -f -w better-sqlite3"
   },
   "dependencies": {
      "@electron-toolkit/preload": "^3.0.1",
      "@electron-toolkit/utils": "^3.0.0",
      "@electron/rebuild": "^3.6.0",
      "await-to-js": "^3.0.0",
      "better-sqlite3": "^11.2.1",
      "electron-rpc-api": "^10.0.0",
      "inversify": "^6.0.2",
      "pg": "^8.4.0",
      "reflect-metadata": "^0.1.13",
      "rxjs": "^7.8.1",
      "staatshelfer": "^0.0.1",
      "typeorm": "0.3.20",
      "zustand": "^4.5.5"
   },
   "devDependencies": {
      "@electron-toolkit/eslint-config-prettier": "^2.0.0",
      "@electron-toolkit/eslint-config-ts": "^2.0.0",
      "@electron-toolkit/tsconfig": "^1.0.1",
      "@types/node": "^16.18.107",
      "@types/react": "^18.3.3",
      "@types/react-dom": "^18.3.0",
      "@vitejs/plugin-react": "^4.3.1",
      "electron": "^31.0.2",
      "electron-builder": "^24.13.3",
      "electron-vite": "^2.3.0",
      "eslint": "^8.57.0",
      "eslint-plugin-react": "^7.34.3",
      "prettier": "^3.3.2",
      "react": "^18.3.1",
      "react-dom": "^18.3.1",
      "ts-node": "10.9.1",
      "typescript": "4.5.2",
      "vite": "^5.3.1"
   }
}

node版本:

$ node -v
v20.12.1
阅读 740
avatarAI BotBETA

针对您在使用 TypeORM 定义 Entity 时遇到的两个问题,我将分别给出解决方案:

1. “作为表达式调用时,无法解析属性修饰器的签名” 错误

这个错误通常与 TypeScript 的配置有关,特别是与 TypeScript 如何处理装饰器(Decorators)有关。在 TypeScript 中,装饰器是一个实验性特性,需要在 tsconfig.json 文件中明确启用。

解决方案

确保您的 tsconfig.json 文件中包含了以下配置来启用装饰器:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    // 其他配置...
  }
}
  • "experimentalDecorators": true 允许使用装饰器。
  • "emitDecoratorMetadata": true 对于 TypeORM 很重要,因为它需要元数据来生成数据库模型。

2. “属性“firstName”没有初始化表达式,且未在构造函数中明确赋值” 错误

这个错误是 TypeScript 的严格空检查(strict null checks)特性导致的。在 TypeScript 的严格模式下,类中的非空属性(如 stringnumber 等类型)必须在构造函数中被明确赋值,或者在声明时给出默认值。

解决方案

您可以在声明属性时给它们一个默认值,或者在构造函数中初始化它们。对于大多数情况,给它们一个默认值(如空字符串或 0)是合理的,特别是如果这些字段在数据库中允许为 NULL 或有默认值。

import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'

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

  @Column()
  firstName: string = ''; // 默认值

  @Column()
  lastName: string = '';  // 默认值

  @Column()
  age: number = 0;        // 默认值
}

或者,在构造函数中初始化它们:

import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'

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

  @Column()
  firstName: string

  @Column()
  lastName: string

  @Column()
  age: number

  constructor(firstName: string = '', lastName: string = '', age: number = 0) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
  }
}

选择哪种方式取决于您的具体需求和偏好。如果这些字段在数据库中总是有值,那么在构造函数中初始化它们可能更好。如果它们可以是空的或可选的,则提供默认值可能更方便。

1 个回答

第一个问题 AI 给答案了,照着改 tsconfig 就好。


第二个问题是你把属性的类型声明成非空的了,但又没给初始值。

要么你声明成可空的:

class Foo {
   bar?: string
}

要么加非空断言符:

class Foo {
   bar!: string
}

看你自己业务里这个字段究竟是否可以置为空。

P.S. AI 给的改法也不是不行,但对于定义 ORM 的 Entity 来说并不是最优解。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏