1
0

More than 1 year has passed since last update.

TypeORMの0.3系でType 'string' has no properties in common with type 'FindOneOptions<T>'と怒られた

Last updated at Posted at 2022-09-24

エラー時の状況

TypeORMの0.3系でfindOneメソッドの使い方ではまったので備忘録。
エラーは以下の通り

src/todo/todo.service.ts:20:46 - error TS2559: Type 'string' has no properties in common with type 'FindOneOptions<Todo>'.

20     return await this.todoRepository.findOne(id);
                                                ~~

問題のコード。

todo.service.ts
@Injectable()
export class TodoService {
  constructor(
    @InjectRepository(Todo)
    private readonly todoRepository: Repository<Todo>,
  ) {}

  async findOne(id: string): Promise<Todo> {
    return await this.todoRepository.findOne(id);
  }
}

環境

package.json
{
  // ...
  "dependencies": {
    "@nestjs/common": "^8.0.0",
    "@nestjs/config": "^2.2.0",
    "@nestjs/core": "^8.0.0",
    "@nestjs/mapped-types": "*",
    "@nestjs/platform-express": "^8.0.0",
    "@nestjs/typeorm": "^9.0.1",
    "class-transformer": "^0.5.1",
    "class-validator": "^0.13.2",
    "pg": "^8.8.0",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^7.2.0",
    "typeorm": "^0.3.9"
  },
  "devDependencies": {
    "@nestjs/cli": "^8.0.0",
    "@nestjs/schematics": "^8.0.0",
    "@nestjs/testing": "^8.0.0",
    "@types/express": "^4.17.13",
    "@types/jest": "27.5.0",
    "@types/node": "^16.0.0",
    "@types/supertest": "^2.0.11",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "eslint": "^8.0.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "jest": "28.0.3",
    "prettier": "^2.3.2",
    "source-map-support": "^0.5.20",
    "supertest": "^6.1.3",
    "ts-jest": "28.0.1",
    "ts-loader": "^9.2.3",
    "ts-node": "^10.0.0",
    "tsconfig-paths": "4.0.0",
    "typescript": "^4.3.5"
  },
  // ...
}

エラーの原因の仮説

パラメータの渡し方もしくは、型になにかしら問題がありそう。

  • TypeORMのfindOneメソッドの引数に渡すパラメーターが間違っている?
  • 型定義が間違っている?

仮説を検証してみる

エラーにも書いてあるように、パラメーターの渡し方が悪そうなので、一旦FindOneOptions<T>を見てみる。
FindOneOptions<T>にはidは渡せなさそう…

TypeORMの公式ドキュメントでfindOneメソッドについて調べている。
すると…

findOne(id) signature was dropped. Use following syntax instead:

const user = await userRepository.findOneBy({
  id: id // where id is your column name
})

https://orkhan.gitbook.io/typeorm/

findOne(id)は使えなくなったよ。代わりにfindOneByを使ってね。」的な事が書いてありました。

公式ドキュメントの通りコードを修正する

以下のようにコードを修正すると…
エラーが解消されました!
修正したAPIにリクエストを送ると、問題なく動作しました!

todo.service.ts
@Injectable()
export class TodoService {
  constructor(
    @InjectRepository(Todo)
    private readonly todoRepository: Repository<Todo>,
  ) {}

  async findOne(id: string): Promise<Todo> {
-    return await this.todoRepository.findOne(id);
+    return await this.todoRepository.findOneBy({ id });
  }
}

🎉🎉🎉

原因

このエラーの原因は以下の通りです。

  • findOneメソッドに渡すパラメータのかたちが間違っていた
  • そもそも、TypeORM0.3.0以降から、findOneメソッドが廃止されていた
    • NestJS8.0.0CRUD generatornest g resource <resource-name>を使うと、自動的にfindOneメソッドを使うようになっている

Source and Thanks

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0