Skip to content

Commit 5339224

Browse files
authored
Merge pull request #2733 from AtCoder-NoviSteps/#2657
chore: Fix type errors (#2657)
2 parents e7ba3fa + 7942e72 commit 5339224

File tree

2 files changed

+106
-8
lines changed

2 files changed

+106
-8
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# TypeScript 5.9 型推論の理解と実装
2+
3+
## 概要
4+
5+
TypeScript 5.9 の型の厳格化により、`prisma/seed.ts` のメソッド引数に型注釈が必要になった。関数パラメータに対して正しい型を推論し、適用した。
6+
7+
## Q&A 要約
8+
9+
### Q1: `(typeof users)[number]` とは?
10+
11+
**A:** 配列型 `users` から要素型を抽出する型操作。
12+
13+
- `typeof users` → 配列型そのもの
14+
- `[number]` → 任意の数値インデックスでアクセスした時の型(全ての要素の共通型)
15+
16+
### Q2: `[number]` は配列のインデックスか?
17+
18+
**A:** 配列の「最初の要素」ではなく、「任意のインデックスでアクセスした結果の型」を意味する型操作。全インデックスで同じ型が返される。
19+
20+
### Q3: `ReturnType<typeof hoge>` とは?
21+
22+
**A:** 関数 `hoge` の戻り値の型を自動抽出する型操作。複雑なファクトリー関数の戻り値型を手動定義せずに取得できる。
23+
24+
## 実装結果
25+
26+
**すべての関数パラメータの型注釈を追加し、関数引数の型推論エラーを完全に解消した。**
27+
28+
```typescript
29+
// addUser 関数
30+
async function addUser(
31+
user: (typeof users)[number],
32+
password: string,
33+
userFactory: ReturnType<typeof defineUserFactory>,
34+
keyFactory: ReturnType<typeof defineKeyFactory>,
35+
);
36+
37+
// addTask 関数
38+
async function addTask(
39+
task: (typeof tasks)[number],
40+
taskFactory: ReturnType<typeof defineTaskFactory>,
41+
);
42+
43+
// addWorkBook 関数
44+
async function addWorkBook(
45+
workbook: (typeof workbooks)[number],
46+
workBookFactory: ReturnType<typeof defineWorkBookFactory>,
47+
);
48+
49+
// addTag 関数
50+
async function addTag(tag: (typeof tags)[number], tagFactory: ReturnType<typeof defineTagFactory>);
51+
52+
// addTaskTag 関数
53+
async function addTaskTag(
54+
task_tag: (typeof task_tags)[number],
55+
taskTagFactory: ReturnType<typeof defineTaskTagFactory>,
56+
);
57+
58+
// addSubmissionStatus 関数
59+
async function addSubmissionStatus(
60+
submission_status: (typeof submission_statuses)[number],
61+
submissionStatusFactory: ReturnType<typeof defineSubmissionStatusFactory>,
62+
);
63+
64+
// addAnswer 関数
65+
async function addAnswer(
66+
answer: (typeof answers)[number],
67+
taskAnswerFactory: ReturnType<typeof defineTaskAnswerFactory>,
68+
);
69+
```
70+
71+
## 教訓
72+
73+
1. **型インデックスアクセス**: `Type[KeyType]` で型から値を抽出できる
74+
2. **配列要素型の抽出**: `(typeof array)[number]` でシンプルに要素型を取得
75+
3. **関数戻り値型の自動抽出**: `ReturnType<typeof fn>` で複雑な型定義を避けられる
76+
4. **TypeScript 5.9 の型安全性**: 関数パラメータの暗黙的 `any` を禁止することで、デバッグ時の型ミスマッチを防げる

prisma/seed.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import {
2020
import PQueue from 'p-queue';
2121
import { generateLuciaPasswordHash } from 'lucia/utils';
2222

23+
import { getTaskGrade } from '../src/lib/types/task';
24+
2325
import { classifyContest } from '../src/lib/utils/contest';
2426

2527
import { users, USER_PASSWORD_FOR_SEED } from './users';
@@ -104,7 +106,12 @@ async function addUsers() {
104106

105107
// See:
106108
// https://lucia-auth.com/reference/lucia/modules/utils/#generateluciapasswordhash
107-
async function addUser(user, password: string, userFactory, keyFactory) {
109+
async function addUser(
110+
user: (typeof users)[number],
111+
password: string,
112+
userFactory: ReturnType<typeof defineUserFactory>,
113+
keyFactory: ReturnType<typeof defineKeyFactory>,
114+
) {
108115
const currentUser = await userFactory.createForConnect({
109116
id: user.id,
110117
username: user.name,
@@ -150,15 +157,18 @@ async function addTasks() {
150157
console.log('Finished adding tasks.');
151158
}
152159

153-
async function addTask(task, taskFactory) {
160+
async function addTask(
161+
task: (typeof tasks)[number],
162+
taskFactory: ReturnType<typeof defineTaskFactory>,
163+
) {
154164
// Note: Task-Tag relationships are handled separately via TaskTag table
155165
await taskFactory.create({
156166
contest_type: classifyContest(task.contest_id),
157167
contest_id: task.contest_id,
158168
task_table_index: task.problem_index,
159169
task_id: task.id,
160170
title: task.title,
161-
grade: task.grade,
171+
grade: getTaskGrade(task.grade as string),
162172
});
163173
}
164174

@@ -223,7 +233,10 @@ async function addWorkBooks() {
223233
console.log('Finished adding workbooks.');
224234
}
225235

226-
async function addWorkBook(workbook, workBookFactory) {
236+
async function addWorkBook(
237+
workbook: (typeof workbooks)[number],
238+
workBookFactory: ReturnType<typeof defineWorkBookFactory>,
239+
) {
227240
const urlSlug = normalizeUrlSlug(workbook.urlSlug);
228241

229242
await workBookFactory.create({
@@ -293,7 +306,7 @@ async function addTags() {
293306
console.log('Finished adding tags.');
294307
}
295308

296-
async function addTag(tag, tagFactory) {
309+
async function addTag(tag: (typeof tags)[number], tagFactory: ReturnType<typeof defineTagFactory>) {
297310
// Note: Tags and Tasks are connected via the TaskTag relationship table
298311
// which is handled separately in addTaskTags()
299312
await tagFactory.create({
@@ -353,7 +366,10 @@ async function addTaskTags() {
353366
await taskTagQueue.onIdle(); // Wait for all task tags to complete
354367
console.log('Finished adding task tags.');
355368
}
356-
async function addTaskTag(task_tag, taskTagFactory) {
369+
async function addTaskTag(
370+
task_tag: (typeof task_tags)[number],
371+
taskTagFactory: ReturnType<typeof defineTaskTagFactory>,
372+
) {
357373
await taskTagFactory.create({
358374
id: task_tag.id,
359375
priority: task_tag.priority,
@@ -398,7 +414,10 @@ async function addSubmissionStatuses() {
398414
console.log('Finished adding submission statuses.');
399415
}
400416

401-
async function addSubmissionStatus(submission_status, submissionStatusFactory) {
417+
async function addSubmissionStatus(
418+
submission_status: (typeof submission_statuses)[number],
419+
submissionStatusFactory: ReturnType<typeof defineSubmissionStatusFactory>,
420+
) {
402421
await submissionStatusFactory.create({
403422
id: submission_status.id,
404423
status_name: submission_status.status_name,
@@ -460,7 +479,10 @@ async function addAnswers() {
460479
console.log('Finished adding answers.');
461480
}
462481

463-
async function addAnswer(answer, taskAnswerFactory) {
482+
async function addAnswer(
483+
answer: (typeof answers)[number],
484+
taskAnswerFactory: ReturnType<typeof defineTaskAnswerFactory>,
485+
) {
464486
await taskAnswerFactory.create({
465487
id: answer.id,
466488
task: {

0 commit comments

Comments
 (0)