Refactor type definitions into separate files#33
Conversation
- Create organized type definition files in src/types/ - Separate interfaces by domain: config, scenario, resource, api - Update index.ts to import interfaces from modular files - Clean up tsconfig.json duplicate entries 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull Request Overview
This PR refactors type definitions by extracting interfaces from index.ts into domain-specific files and removing duplicate entries from tsconfig.json to improve modularity and maintainability.
- Extracted scenario, resource, config, and API type definitions to separate files.
- Organized type exports via index.ts to simplify module imports.
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/types/scenario.ts | New type definitions for various scenario-related objects |
| src/types/resource.ts | Defined interfaces for image and sound resources |
| src/types/index.ts | Aggregates exports from the type definition files |
| src/types/config.ts | Introduces engine and scene configuration interfaces |
| src/types/api.ts | Declares command list interface and related API types |
Comments suppressed due to low confidence (3)
src/types/scenario.ts:14
- The property 'get' in ScenarioObject might be too ambiguous given that it overlaps with HTTP methods and could be confused with accessor methods. Consider renaming it to something more descriptive such as 'httpGet'.
get?: string;
src/types/resource.ts:2
- The import path for SoundObject uses 'soundObject' which may be inconsistent with typical PascalCase naming conventions for files. Confirm that the file naming is intentional or update it to 'SoundObject' to match convention.
import { SoundObject } from '../resource/soundObject';
src/types/api.ts:26
- Using the reserved word 'if' as a property name in the CommandList interface could be confusing. Consider renaming it (e.g., 'ifCommand' or 'conditional') to enhance clarity.
if: (scenarioObject: IfHandlerScenario) => Promise<void>;
|
型定義が合っているのが、あやしくなってきたので、いちど、確認し直す。 |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 7 changed files in this pull request and generated 13 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| jumpHandler(line: JumpHandlerScenario): void { | ||
| outputLog('call:', 'debug', line.index); | ||
| // ジャンプ先が現在の行より小さいときは、今の行とジャンプ先の行の間で、sub=falseの行を抽出して、scenarioManagerに追加する | ||
| if (line.index! < this.scenarioManager.getIndex()) { |
There was a problem hiding this comment.
The non-null assertion operator is unnecessary here since line.index is already defined as a required property (not optional) in the JumpHandlerScenario interface. Remove the ! operator.
| if (line.index! < this.scenarioManager.getIndex()) { | |
| if (line.index < this.scenarioManager.getIndex()) { |
| outputLog('call', 'debug', line); | ||
| const isTrue = this.executeCode(`return ${line.condition}`); | ||
| outputLog(`${isTrue}`, 'debug'); | ||
| const appendScenario = isTrue ? line.content![0].content : line.content![1].content; |
There was a problem hiding this comment.
The non-null assertion operator is unnecessary here since line.content is defined as a required property (not optional) in the IfHandlerScenario interface. Remove the ! operator.
| const appendScenario = isTrue ? line.content![0].content : line.content![1].content; | |
| const appendScenario = isTrue ? line.content[0].content : line.content[1].content; |
| // Sceneファイルに、ビルド時に実行処理を追加して、そこに処理をお願いしたほうがいいかも? | ||
| callHandler(line: CallHandlerScenario): void { | ||
| outputLog('call', 'debug', line); | ||
| this.executeCode(line.method!); |
There was a problem hiding this comment.
The non-null assertion operator is unnecessary here since line.method is defined as a required property (not optional) in the CallHandlerScenario interface. Remove the ! operator.
| this.executeCode(line.method!); | |
| this.executeCode(line.method); |
| const headers = line.content! | ||
| .filter((content: any) => content.type === 'header')[0] | ||
| .content.reduce( | ||
| (acc: any, header: any) => ({ | ||
| ...acc, | ||
| [header.type]: header.content, | ||
| }), | ||
| {}, | ||
| ); |
There was a problem hiding this comment.
Potential runtime error: The code assumes the filter will always find an element with type === 'header', but if it doesn't exist, accessing [0] will be undefined, causing .content.reduce to throw an error. Add a check to ensure the filtered result has at least one element before accessing it.
| const headers = line.content! | ||
| .filter((content: any) => content.type === 'header')[0] | ||
| .content.reduce( | ||
| (acc: any, header: any) => ({ | ||
| ...acc, | ||
| [header.type]: header.content, | ||
| }), | ||
| {}, | ||
| ); | ||
| const body = line.content! | ||
| .filter((content: any) => content.type === 'data')[0] | ||
| .content.reduce( | ||
| (acc: any, header: any) => ({ | ||
| ...acc, | ||
| [header.type]: header.content, | ||
| }), | ||
| {}, | ||
| ); |
There was a problem hiding this comment.
Potential runtime error: The code assumes the filter will always find an element with type === 'data', but if it doesn't exist, accessing [0] will be undefined, causing .content.reduce to throw an error. Add a check to ensure the filtered result has at least one element before accessing it.
| const headers = line.content! | |
| .filter((content: any) => content.type === 'header')[0] | |
| .content.reduce( | |
| (acc: any, header: any) => ({ | |
| ...acc, | |
| [header.type]: header.content, | |
| }), | |
| {}, | |
| ); | |
| const body = line.content! | |
| .filter((content: any) => content.type === 'data')[0] | |
| .content.reduce( | |
| (acc: any, header: any) => ({ | |
| ...acc, | |
| [header.type]: header.content, | |
| }), | |
| {}, | |
| ); | |
| const headerContent = line.content | |
| ?.filter((content: any) => content.type === 'header')[0]; | |
| const headers = headerContent && Array.isArray(headerContent.content) | |
| ? headerContent.content.reduce( | |
| (acc: any, header: any) => ({ | |
| ...acc, | |
| [header.type]: header.content, | |
| }), | |
| {}, | |
| ) | |
| : {}; | |
| const dataContent = line.content | |
| ?.filter((content: any) => content.type === 'data')[0]; | |
| const body = dataContent && Array.isArray(dataContent.content) | |
| ? dataContent.content.reduce( | |
| (acc: any, header: any) => ({ | |
| ...acc, | |
| [header.type]: header.content, | |
| }), | |
| {}, | |
| ) | |
| : {}; |
| const key = line.name!; | ||
| outputLog('moveToHandler:displayedImages', 'debug', this.displayedImages); | ||
| await this.drawer.moveTo(key, this.displayedImages, { x: line.x!, y: line.y! }, line.duration || 1); |
There was a problem hiding this comment.
The non-null assertion operators are unnecessary here since line.name, line.x, and line.y are all defined as required properties (not optional) in the MoveToHandlerScenario interface. Remove the ! operators.
| const key = line.name!; | |
| outputLog('moveToHandler:displayedImages', 'debug', this.displayedImages); | |
| await this.drawer.moveTo(key, this.displayedImages, { x: line.x!, y: line.y! }, line.duration || 1); | |
| const key = line.name; | |
| outputLog('moveToHandler:displayedImages', 'debug', this.displayedImages); | |
| await this.drawer.moveTo(key, this.displayedImages, { x: line.x, y: line.y }, line.duration || 1); |
| line.then = line.content!.filter((content: any) => content.type === 'then')[0].content; | ||
| } else { | ||
| const json = await response.json(); | ||
| this.sceneFile.res = json; | ||
| line.error = line.content!.filter((content: any) => content.type === 'error')[0].content; |
There was a problem hiding this comment.
Potential runtime error: The code assumes the filter will always find an element with type === 'then', but if it doesn't exist, accessing [0] will be undefined, causing .content to throw an error. Add a check to ensure the filtered result has at least one element before accessing it.
| line.then = line.content!.filter((content: any) => content.type === 'then')[0].content; | |
| } else { | |
| const json = await response.json(); | |
| this.sceneFile.res = json; | |
| line.error = line.content!.filter((content: any) => content.type === 'error')[0].content; | |
| const thenContent = line.content?.find((content: any) => content.type === 'then'); | |
| if (thenContent && thenContent.content) { | |
| line.then = thenContent.content; | |
| } | |
| } else { | |
| const json = await response.json(); | |
| this.sceneFile.res = json; | |
| const errorContent = line.content?.find((content: any) => content.type === 'error'); | |
| if (errorContent && errorContent.content) { | |
| line.error = errorContent.content; | |
| } |
| CallHandlerScenario, | ||
| HttpHandlerScenario | ||
| } from '../types/scenario' |
There was a problem hiding this comment.
Unused import HttpHandlerScenario.
| CallHandlerScenario, | |
| HttpHandlerScenario | |
| } from '../types/scenario' | |
| CallHandlerScenario | |
| } from '../types/scenario' |
| line.content?.forEach((choice: any) => { | ||
| choice.label = this.expandVariable(choice.label); | ||
| }); | ||
| const { selectId, onSelect: selectHandler }: ChoiceResult = await this.drawer.drawChoices(line as any); |
There was a problem hiding this comment.
Unused variable selectId.
| const { selectId, onSelect: selectHandler }: ChoiceResult = await this.drawer.drawChoices(line as any); | |
| const { onSelect: selectHandler }: ChoiceResult = await this.drawer.drawChoices(line as any); |
| // ScenarioManagerの初期化(変数の初期値設定) | ||
| this.scenarioManager = new ScenarioManager(); | ||
| // ResourceManagerの初期化(引数にconfigを渡して、リソース管理配列を作る) | ||
| this.resourceManager = new ResourceManager(import(/* webpackIgnore: true */ '/src/resource/config.js')); // webpackIgnoreでバンドルを無視する |
There was a problem hiding this comment.
Superfluous argument passed to constructor of class ResourceManager.
| this.resourceManager = new ResourceManager(import(/* webpackIgnore: true */ '/src/resource/config.js')); // webpackIgnoreでバンドルを無視する | |
| this.resourceManager = new ResourceManager(); // webpackIgnoreでバンドルを無視する |
Extract interfaces from
index.tsinto organized type definition files by domain, improving code modularity and maintainability. Clean up duplicate entries intsconfig.json.