Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions react/src/practice/_components/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
interface Props {
onClick: () => void;
children: React.ReactNode;
}

export const Button = ({ children, onClick }: Props) => {
return <button onClick={onClick}>{children}</button>;
};
2 changes: 1 addition & 1 deletion react/src/practice/practice_1/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
// 以下のコードを完成させて、画面に「Hello, World!」と表示してください。

export const Practice1 = () => {
return <>{/* コードをここに書いてください */}</>;
return <div>Hello, World!</div>;
};
2 changes: 1 addition & 1 deletion react/src/practice/practice_2/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@

export const Practice2 = () => {
const name = 'Hello, React!';
return <h1></h1>;
return <h1>{name}</h1>;
};
10 changes: 8 additions & 2 deletions react/src/practice/practice_3/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
// 以下のコードを完成させて、isLoggedInがtrueの場合「Welcome back!」、それ以外の場合「Please sign in.」と表示するようにしてください。

export const Practice3 = () => {
let isLoggedIn: boolean;
return <></>;
let isLoggedIn: boolean = true;
let result = "";
if (isLoggedIn) {
result = 'Welcome back!';
} else {
result = 'Please sign in.';
}
return <div>{result}</div>;
};
8 changes: 7 additions & 1 deletion react/src/practice/practice_4/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,11 @@ export const Practice4 = () => {
{ id: 2, name: 'Banana' },
{ id: 3, name: 'Cherry' },
];
return <ul>{/* items配列を使ってリストを作成してください */}</ul>;
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
};
20 changes: 18 additions & 2 deletions react/src/practice/practice_5/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// 演習5:商品リストの作成

import { Button } from '@/practice/_components/button';
import { Counter } from '@/practice/practice_6';

// MUST要件
// 商品リストを表示する。(例:Apple, Banana, Cherry)
// 商品ごとに「詳細を見る」ボタンを表示する。
Expand All @@ -18,7 +21,20 @@ export const Practice5 = () => {
];

return (
<>
</>
<ul>
{products.map((product) => (
<li key={product.id}>
{product.name}
<Button
onClick={() => {
alert(`商品名: ${product.name} 価格: ${product.price}`);
}}
>
詳細を見る
</Button>
<Counter />
</li>
))}
</ul>
);
};
25 changes: 22 additions & 3 deletions react/src/practice/practice_6/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
// 問題1: useStateを使ったカウンター
// 次の条件を満たすカウンターコンポーネントを作成してください:

import { Button } from '@/practice/_components/button';
import { useState } from 'react';

// 初期値を0に設定します。
// 「増加」「減少」「リセット」の3つのボタンを追加します。
// ボタンをクリックすると、それぞれの機能が正しく動作します。

export const Practice6 = () => {
return <>{/* コードをここに書いてください */}</>;
}
// export const Practice6 = () => {
export const Counter = () => {
const [count, setCount] = useState(0);

const increase = () => setCount(count + 1);
const decrease = () => setCount(count - 1);
const reset = () => setCount(0);

return (
<>
<div>
<Button onClick={increase}>増加</Button>
<Button onClick={decrease}>減少</Button>
<Button onClick={reset}>リセット</Button>
</div>
<div>{count}</div>
</>
);
};
36 changes: 34 additions & 2 deletions react/src/practice/practice_7/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// 問題2: useEffectを使ったデータ取得
// 以下の条件を満たすデータ取得コンポーネントを作成してください:

import { useEffect, useState } from 'react';

// コンポーネントがマウントされたときにfetchDataからデータを取得します。
// データ取得中は「Loading...」と表示します。
// データ取得後は、取得した内容をリスト形式で表示します。
Expand All @@ -23,5 +25,35 @@ const fetchData = () => {
};

export const Practice7 = () => {
return <>{/* コードをここに書いてください */}</>;
}
const [data, setData] = useState<DataItem[]>([]);
const [loading, setLoading] = useState<boolean>(true);

useEffect(() => {
const getData = async () => {
try {
const result = await fetchData();
setData(result);
} catch (error) {
console.error('Failed Data Fetch', error);
}

setLoading(false);
};

getData();
}, []);

return (
<div>
{loading ? (
<div>Loading...</div>
) : (
<ul>
{data?.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
)}
</div>
);
};
2 changes: 2 additions & 0 deletions react/src/root/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Practice2 } from '@/practice/practice_2';
import { Practice3 } from '@/practice/practice_3';
import { Practice4 } from '@/practice/practice_4';
import { Practice5 } from '@/practice/practice_5';
import { Practice7 } from '@/practice/practice_7';

export const Root = () => {
return (
Expand All @@ -12,6 +13,7 @@ export const Root = () => {
<Practice3 />
<Practice4 />
<Practice5 />
<Practice7 />
</>
);
};
13 changes: 8 additions & 5 deletions typescript/src/practice_1/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
// 演習1: 以下のコードに適切な型注釈を付けてください。
let username = 'John'; // 型: ?
let age = 30; // 型: ?
let isAdmin = true; // 型: ?
let hoge: "hoge";
const huga = "huga";

let scores = [100, 90, 80]; // 型: ?
let username: string = 'John'; // 型: ?
let age: number = 30; // 型: ?
let isAdmin: boolean = true; // 型: ?

let user = {
let scores: number[] = [100, 90, 80]; // 型: ?

let user: {id: number; name: string; isActive: boolean;} = {
id: 1,
name: 'John',
isActive: true,
Expand Down
17 changes: 12 additions & 5 deletions typescript/src/practice_2/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
// 演習2: 以下の関数に型を追加してください。

// 以下のコメントを外して問題を解く
// function add(a, b) {
// return a + b;
// }
function add(a: number, b: number): number {
return a + b;
}

// function formatId(id) {


function formatId(id: string): string {
return `ID: ${id}`;
}

// これもいける
// function formatId(id: number): string {
// return `ID: ${id}`;
// }
// }
25 changes: 16 additions & 9 deletions typescript/src/practice_3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@
// Todo の状態を表す Union 型を type を使って定義してください。

// 以下のコメントを外して問題を解く
// type TodoStatus = ;

// interface Todo {
// }
// 複雑指定できる
type TodoStatus = { id: number; text: string; status: "todo" | "in-progress" | "done"; };

// // 次の配列が型チェックを通過するようにしてください。
// let todos: Todo[] = [
// { id: 1, text: "Learn TypeScript", status: "todo" },
// { id: 2, text: "Build a project", status: "in-progress" },
// { id: 3, text: "Review code", status: "done" },
// ];
// interfaceはobjectに
interface Todo {
id: number;
text: string;
status: "todo" | "in-progress" | "done";
}

// 次の配列が型チェックを通過するようにしてください。
let todos: Todo[] = [
{ id: 1, text: "Learn TypeScript", status: "todo" },
{ id: 2, text: "Build a project", status: "in-progress" },
{ id: 3, text: "Review code", status: "done" },
// { id: 4, text: "test", status: "hoge" }, // Union型でエラーする
];
19 changes: 16 additions & 3 deletions typescript/src/practice_4/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ const input = document.querySelector('input');
// エラーを解消してください。

// 以下のコメントを外して問題を解く
// button.onclick = () => {
// console.log(`Input length: ${input.length}`);
// };

if (button instanceof HTMLButtonElement && input instanceof HTMLInputElement) {
button.onclick = () => {
console.log(`Input length: ${input.value.length}`);
};
}

// 解答例
// const buttonAnswer = document.querySelector('button');
// const inputAnswer = document.querySelector('input');

// if (button && input) {
// button.onclick = () => {
// console.log(`Input length: ${input.value.length}`);
// };
// }
26 changes: 11 additions & 15 deletions typescript/src/practice_5/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,20 @@
// 次の型を完成させてください。

// 問題1: 戻り値の型を取得する
// 関数 T の戻り値の型を取得する型 `MyReturnType` を作成してください。

// ヒント:
// - 戻り値の型を取得するには、`infer` を使用して型を推論します。
// - https://typescriptbook.jp/reference/type-reuse/infer
type MyReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : never;

// 使用例:
// type Foo = () => number;
// type Bar = () => string;
type Foo = () => number;
type Bar = () => string;

// 問題2: オブジェクトの特定のキーを省略する型
// オブジェクト T からキー K を省略する型 `OmitKey` を作成してください。
type FooReturnType = MyReturnType<Foo>; // number
type BarReturnType = MyReturnType<Bar>; // string

// ヒント:
// - `Exclude` ユーティリティ型を使用して、特定のキーを取り除きます。
// - 構文: `Exclude<keyof T, K>`
// - 残ったキーで新しいオブジェクト型を構築します。
// 問題2: オブジェクトの特定のキーを省略する型
type OmitKey<T, K extends keyof T> = {
[P in Exclude<keyof T, K>]: T[P];
};

// 使用例:
// type User = { id: number; name: string; age: number };
// type WithoutAge = OmitKey<User, "age">; // { id: number; name: string; }
type User = { id: number; name: string; age: number };
type WithoutAge = OmitKey<User, "age">; // { id: number; name: string; }