å ç¢ãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®TypeScriptã®ãšã©ãŒå¢çããã¹ã¿ãŒããŸããããæ§ã ãªãšã©ãŒãã³ããªã³ã°åãã¿ãŒã³ããã¹ããã©ã¯ãã£ã¹ãå®äŸãæ¢ããŸãã
TypeScriptã®ãšã©ãŒå¢çïŒå ç¢ãªã¢ããªã±ãŒã·ã§ã³ã®ããã®ãšã©ãŒãã³ããªã³ã°åãã¿ãŒã³
ãœãããŠã§ã¢éçºã®äžçã§ã¯ãäºæãã¬ãšã©ãŒã¯é¿ããããŸããããããã¯ãŒã¯ã®äžå ·åããäºæããªãããŒã¿åœ¢åŒãŸã§ãã¢ããªã±ãŒã·ã§ã³ã¯ãããã®ç¶æ³ã«é©åã«å¯ŸåŠããæºåãã§ããŠããªããã°ãªããŸãããTypeScriptã¯ããã®åŒ·åãªåã·ã¹ãã ã«ãããå埩åã®ããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®å ç¢ãªãã¬ãŒã ã¯ãŒã¯ãæäŸããŸãããã®èšäºã§ã¯ãTypeScriptã®ãšã©ãŒå¢çã®æŠå¿µãæãäžããããŸããŸãªãšã©ãŒãã³ããªã³ã°åãã¿ãŒã³ããã¹ããã©ã¯ãã£ã¹ããããŠããå®å®ãä¿å®æ§ã®é«ãã³ãŒããäœæããããã®ç¥èã身ã«ã€ããããã®å®äžçã®äŸãæ¢ããŸãã
ãšã©ãŒãã³ããªã³ã°ã®éèŠæ§ãçè§£ãã
广çãªãšã©ãŒãã³ããªã³ã°ã¯ãåªãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãšã¢ããªã±ãŒã·ã§ã³å šäœã®å¥å šæ§ã«ãšã£ãŠéåžžã«éèŠã§ãããšã©ãŒãåŠçãããªããŸãŸã ãšã以äžã®ãããªäºæ ã«ã€ãªããå¯èœæ§ããããŸãïŒ
- ã¯ã©ãã·ã¥ãšäºæž¬äžèœãªåäœïŒ ææãããªãäŸå€ã¯ã³ãŒãã®å®è¡ã忢ãããã¯ã©ãã·ã¥ãäºæž¬äžèœãªçµæãåŒãèµ·ããå¯èœæ§ããããŸãã
- ããŒã¿ã®æå€±ãšç ŽæïŒ ããŒã¿åŠçäžãä¿åäžã®ãšã©ãŒã¯ãããŒã¿ã®æå€±ãç Žæã«ã€ãªããããŠãŒã¶ãŒãã·ã¹ãã ã®å®å šæ§ã«åœ±é¿ãäžããŸãã
- ã»ãã¥ãªãã£ã®è匱æ§ïŒ äžé©åãªãšã©ãŒãã³ããªã³ã°ã¯ãæ©å¯æ å ±ãæŒæŽ©ãããããæªæã®ããæ»æã®æ©äŒãäœãåºãããããå¯èœæ§ããããŸãã
- ãã¬ãã£ããªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ïŒ äžå¯è§£ãªãšã©ãŒã¡ãã»ãŒãžãã¢ããªã±ãŒã·ã§ã³ã®é害ã«ééãããŠãŒã¶ãŒã¯ãäžæºãªäœéšãããä¿¡é Œãšæ¡çšã®åªå€±ã«ã€ãªãããŸãã
- çç£æ§ã®äœäžïŒ éçºè ã¯æªåŠçã®ãšã©ãŒã®ãããã°ãšè§£æ±ºã«æéãè²»ãããéçºå šäœã®çç£æ§ã劚ãããªãªãŒã¹ãµã€ã¯ã«ãé ãããŸãã
äžæ¹ãåªãããšã©ãŒãã³ããªã³ã°ã¯ä»¥äžãæäŸããŸãïŒ
- ã°ã¬ãŒã¹ãã«ã»ãã°ã©ããŒã·ã§ã³ïŒ ç¹å®ã®éšåã§ãšã©ãŒãçºçããŠããã¢ããªã±ãŒã·ã§ã³ã¯æ©èœãç¶ããŸãã
- æçãªãã£ãŒãããã¯ïŒ ãŠãŒã¶ãŒã¯æç¢ºã§ç°¡æœãªãšã©ãŒã¡ãã»ãŒãžãåãåããåé¡ãçè§£ã解決ããã®ã«åœ¹ç«ã¡ãŸãã
- ããŒã¿ã®å®å šæ§ïŒ éèŠãªæäœã¯ãã©ã³ã¶ã¯ã·ã§ã³çã«ç®¡çãããéèŠãªãŠãŒã¶ãŒæ å ±ãä¿è·ããŸãã
- å®å®æ§ã®åäžïŒ ã¢ããªã±ãŒã·ã§ã³ã¯äºæãã¬ã€ãã³ãã«å¯ŸããŠããå埩åãé«ãŸããŸãã
- ä¿å®æ§ã®åäžïŒ åé¡ãçºçããéã«ãç¹å®ã蚺æãä¿®æ£ã容æã«ãªããŸãã
TypeScriptã«ããããšã©ãŒå¢çãšã¯ïŒ
ãšã©ãŒå¢çã¯ãã³ã³ããŒãã³ãããªãŒã®ç¹å®ã®éšåå ã§JavaScriptã®ãšã©ãŒãææããã¢ããªã±ãŒã·ã§ã³å šäœãã¯ã©ãã·ã¥ããã代ããã«ãã©ãŒã«ããã¯UIãé©åã«è¡šç€ºããããã«äœ¿çšããããã¶ã€ã³ãã¿ãŒã³ã§ããTypeScriptèªäœã«ã¯ç¹å®ã®ããšã©ãŒå¢çãæ©èœã¯ãããŸãããããã®ãããªå¢çãäœæããããã®ååãšãã¯ããã¯ã¯ãTypeScriptã®åå®å šæ§ã«ãã£ãŠå®¹æã«é©çšããã匷åãããŸãã
äžå¿çãªèãæ¹ã¯ããšã©ãŒãçºçããããã³ãŒããå°çšã®ã³ã³ããŒãã³ããã¢ãžã¥ãŒã«å ã«éé¢ããããšã§ãããã®ã³ã³ããŒãã³ãã¯ã©ãããŒãšããŠæ©èœããå éšã®ã³ãŒããç£èŠããŸãããšã©ãŒãçºçããå Žåããšã©ãŒå¢çã³ã³ããŒãã³ãããšã©ãŒããææããããããã³ã³ããŒãã³ãããªãŒãé¡ã£ãŠäŒæããã¢ããªã±ãŒã·ã§ã³ãã¯ã©ãã·ã¥ãããå¯èœæ§ãé²ããŸãã代ããã«ããšã©ãŒå¢çã¯ãã©ãŒã«ããã¯UIãã¬ã³ããªã³ã°ãããããšã©ãŒããã°ã«èšé²ããããåé¡ããã®å埩ã詊ã¿ããããããšãã§ããŸãã
ãšã©ãŒå¢çã䜿çšããå©ç¹ã¯æ¬¡ã®ãšããã§ãïŒ
- åé¢ïŒ ã¢ããªã±ãŒã·ã§ã³ã®ããéšåã®ãšã©ãŒãä»ã®éšåã«åœ±é¿ãäžããã®ãé²ããŸãã
- ãã©ãŒã«ããã¯UIïŒ å®å šã«å£ããã¢ããªã±ãŒã·ã§ã³ããããŠãŒã¶ãŒãã¬ã³ããªãŒãªäœéšãæäŸããŸãã
- ãšã©ãŒãã®ã³ã°ïŒ ãããã°ãšç£èŠã®ããã®ãšã©ãŒæ å ±ã®åéã容æã«ããŸãã
- ä¿å®æ§ã®åäžïŒ ãšã©ãŒãã³ããªã³ã°ããžãã¯ãç°¡çŽ åããã³ãŒãã®æŽæ°ãšä¿å®ã容æã«ããŸãã
TypeScriptã«ããããšã©ãŒãã³ããªã³ã°åãã¿ãŒã³
TypeScriptã®åã·ã¹ãã ã¯ãé©åãªãšã©ãŒãã³ããªã³ã°ãã¿ãŒã³ãšçµã¿åãããããšã§éåžžã«å¹æçã§ãã以äžã«ãTypeScriptã¢ããªã±ãŒã·ã§ã³ã§ãšã©ãŒã管çããããã®äžè¬çã§å¹æçãªãã¿ãŒã³ãããã€ã玹ä»ããŸãïŒ
1. Try-Catchãããã¯
JavaScriptãšTypeScriptã«ããããšã©ãŒãã³ããªã³ã°ã®åºæ¬çãªæ§æèŠçŽ ã¯`try-catch`ãããã¯ã§ããããã«ããã`try`ãããã¯å ã§ã³ãŒããå®è¡ããã¹ããŒãããäŸå€ããã£ããããããšãã§ããŸããããã¯åæçãªæäœã§ããã颿°å ã§çŽæ¥ãšã©ãŒãåŠçããã®ã«çæ³çã§ãã
function fetchData(url: string): Promise<any> {
try {
return fetch(url).then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
});
} catch (error) {
console.error("An error occurred while fetching data:", error);
// Handle the error (e.g., display an error message to the user)
return Promise.reject(error);
}
}
ãã®äŸã§ã¯ã`fetchData`颿°ãæå®ãããURLããããŒã¿ãååŸããããšããŸãã`fetch`åŒã³åºãã倱æããå ŽåïŒäŸïŒãããã¯ãŒã¯ãšã©ãŒãäžæ£ãªURLïŒããŸãã¯ã¬ã¹ãã³ã¹ã®ã¹ããŒã¿ã¹ãæ£åžžã§ãªãå Žåããšã©ãŒãã¹ããŒãããŸãã`catch`ãããã¯ããã®ãšã©ãŒãåŠçããŸãããšã©ãŒãäŒæãããããã«`Promise.reject(error)`ã䜿çšããŠããç¹ã«æ³šæããŠãã ãããããã«ãããåŒã³åºãå ã®ã³ãŒãããšã©ãŒãåŠçã§ããŸããããã¯éåææäœã§äžè¬çã§ãã
2. Promiseãšéåæãšã©ãŒãã³ããªã³ã°
éåææäœã¯JavaScriptã§ã¯äžè¬çã§ãããç¹ã«APIãããŒã¿ããŒã¹æäœããã¡ã€ã«I/Oãæ±ãéã«ããèŠãããŸããPromiseã¯ããããã®ã·ããªãªã§ãšã©ãŒãåŠçããããã®åŒ·åãªã¡ã«ããºã ãæäŸããŸãã`try-catch`ãããã¯ã䟿å©ã§ãããå€ãã®å ŽåãPromiseã®`.then()`ã¡ãœãããš`.catch()`ã¡ãœããå ã§ãšã©ãŒãåŠçããŸãã
function fetchData(url: string): Promise<any> {
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.catch(error => {
console.error("An error occurred while fetching data:", error);
// Handle the error (e.g., display an error message to the user)
return Promise.reject(error);
});
}
fetchData('https://api.example.com/data')
.then(data => {
console.log("Data fetched successfully:", data);
})
.catch(error => {
console.error("Failed to fetch data:", error);
// Display a user-friendly error message
});
ãã®äŸã§ã¯ã`fetchData`颿°ã¯Promiseã䜿çšããŠéåæã®`fetch`æäœãåŠçããŸãããšã©ãŒã¯`.catch()`ãããã¯ã§ææãããéåææäœã«ç¹åããŠãšã©ãŒãåŠçããããšãã§ããŸãã
3. ãšã©ãŒã¯ã©ã¹ãšã«ã¹ã¿ã ãšã©ãŒå
TypeScriptã§ã¯ã«ã¹ã¿ã ãšã©ãŒã¯ã©ã¹ãå®çŸ©ã§ããããæ§é åãããæçãªãšã©ãŒãã³ããªã³ã°ãæäŸããŸããããã¯ãåå©çšå¯èœã§åå®å šãªãšã©ãŒãã³ããªã³ã°ããžãã¯ãäœæããããã®çŽ æŽãããå®è·µæ¹æ³ã§ããã«ã¹ã¿ã ãšã©ãŒã¯ã©ã¹ãäœæããããšã§ã以äžã®ããšãå¯èœã«ãªããŸãïŒ
- ç¹å®ã®ãšã©ãŒã³ãŒãã远å ããïŒ æ§ã ãªãšã©ãŒã¿ã€ããåºå¥ããŸãã
- ã³ã³ããã¹ããæäŸããïŒ ãšã©ãŒã«é¢é£ãã远å ããŒã¿ãä¿åããŸãã
- å¯èªæ§ãšä¿å®æ§ãåäžãããïŒ ãšã©ãŒãã³ããªã³ã°ã³ãŒããçè§£ããããããŸãã
class ApiError extends Error {
statusCode: number;
code: string;
constructor(message: string, statusCode: number, code: string) {
super(message);
this.name = 'ApiError';
this.statusCode = statusCode;
this.code = code;
// Assign the prototype explicitly
Object.setPrototypeOf(this, ApiError.prototype);
}
}
async function getUserData(userId: number): Promise<any> {
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
let errorMessage = 'Failed to fetch user data';
if (response.status === 404) {
errorMessage = 'User not found';
}
throw new ApiError(errorMessage, response.status, 'USER_NOT_FOUND');
}
return await response.json();
} catch (error: any) {
if (error instanceof ApiError) {
console.error("API Error:", error.message, error.statusCode, error.code);
// Handle specific API error based on the code
if (error.code === 'USER_NOT_FOUND') {
// Show a 'user not found' message
}
} else {
console.error("An unexpected error occurred:", error);
// Handle other errors
}
throw error; // Re-throw or handle the error
}
}
getUserData(123)
.then(userData => console.log("User data:", userData))
.catch(error => console.error("Error retrieving user data:", error));
ãã®äŸã§ã¯ãçµã¿èŸŒã¿ã®`Error`ã¯ã©ã¹ãç¶æ¿ãã`ApiError`ã¯ã©ã¹ãå®çŸ©ããŠããŸããããã«ã¯ãããå€ãã®ã³ã³ããã¹ããæäŸããããã«`statusCode`ãš`code`ããããã£ãå«ãŸããŠããŸãã`getUserData`颿°ã¯ãã®ã«ã¹ã¿ã ãšã©ãŒã¯ã©ã¹ã䜿çšããç¹å®ã®ãšã©ãŒã¿ã€ããææããŠåŠçããŸãã`instanceof`æŒç®åã䜿çšããããšã§ãåå®å šãªãã§ãã¯ãšãšã©ãŒã®ã¿ã€ãã«åºã¥ããç¹å®ã®ãšã©ãŒãã³ããªã³ã°ãå¯èœã«ãªããŸãã
4. `Result`åïŒé¢æ°åãšã©ãŒãã³ããªã³ã°ïŒ
颿°åããã°ã©ãã³ã°ã§ã¯ãæåããçµæãŸãã¯ãšã©ãŒã®ããããã衚ãããã«`Result`åïŒ`Either`åãšãåŒã°ããïŒããã䜿çšãããŸãããã®ãã¿ãŒã³ã¯ããšã©ãŒãã¯ãªãŒã³ã§åå®å šãªæ¹æ³ã§åŠçããæ¹æ³ãæäŸããŸãã`Result`åã¯éåžžã`Ok`ïŒæåçšïŒãš`Err`ïŒå€±æçšïŒã®2ã€ã®ããªã¢ã³ããæã¡ãŸãã
// Define a generic Result type
interface Ok<T> {
type: 'ok';
value: T;
}
interface Err<E> {
type: 'err';
error: E;
}
type Result<T, E> = Ok<T> | Err<E>
function divide(a: number, b: number): Result<number, string> {
if (b === 0) {
return { type: 'err', error: 'Division by zero' };
}
return { type: 'ok', value: a / b };
}
const result1 = divide(10, 2);
const result2 = divide(10, 0);
if (result1.type === 'ok') {
console.log('Result:', result1.value);
} else {
console.error('Error:', result1.error);
}
if (result2.type === 'ok') {
console.log('Result:', result2.value);
} else {
console.error('Error:', result2.error);
}
`divide`颿°ã¯ãå²ãç®ã®çµæãå«ã`Ok`åã®`Result`ãããšã©ãŒã¡ãã»ãŒãžãå«ã`Err`åã®`Result`ã®ãããããè¿ããŸãããã®ãã¿ãŒã³ã¯ãåŒã³åºãå ãæåãšå€±æã®äž¡æ¹ã®ã·ããªãªãæç€ºçã«åŠçããããšã匷å¶ããæªåŠçã®ãšã©ãŒãé²ããŸãã
5. ãã³ã¬ãŒã¿ïŒé«åºŠãªãšã©ãŒãã³ããªã³ã°çš - å¢çã®å®è£ ã«ã¯çŽæ¥ã¯ã»ãšãã©äœ¿çšãããªãïŒ
ãšã©ãŒå¢çã®çŽæ¥çãªãã¿ãŒã³ã§ã¯ãããŸãããããã³ã¬ãŒã¿ã䜿çšããŠã¡ãœããã«å®£èšçãªæ¹æ³ã§ãšã©ãŒãã³ããªã³ã°ããžãã¯ãé©çšããããšãã§ããŸããããã«ãããã³ãŒãå ã®å®åçãªèšè¿°ãæžããããšãã§ããŸãããã ãããã®äœ¿çšæ³ã¯ãäžå¿çãªãšã©ãŒå¢çã®å®è£ ã«ãããŠã¯äžèšã®ä»ã®ãã¿ãŒã³ã»ã©äžè¬çã§ã¯ãããŸããã
function handleError(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) {
try {
const result = await originalMethod.apply(this, args);
return result;
} catch (error: any) {
console.error(`Error in ${propertyKey}:`, error);
// Handle the error here (e.g., log, display a default value, etc.)
return null; // Or throw a more specific error
}
};
return descriptor;
}
class MyService {
@handleError
async fetchData(url: string): Promise<any> {
// Simulate an error
if (Math.random() < 0.5) {
throw new Error('Simulated network error');
}
const response = await fetch(url);
return await response.json();
}
}
ãã®äŸã§ã¯`@handleError`ãã³ã¬ãŒã¿ãå®çŸ©ããŠããŸãããã³ã¬ãŒã¿ã¯å ã®ã¡ãœãããã©ãããããšã©ãŒãææããŠãã°ã«èšé²ããŸããããã«ãããå ã®ã¡ãœããã®ã³ãŒããçŽæ¥å€æŽããããšãªããšã©ãŒãã³ããªã³ã°ãå¯èœã«ãªããŸãã
ããã³ããšã³ããã¬ãŒã ã¯ãŒã¯ã§ã®ãšã©ãŒå¢çã®å®è£ ïŒReactã®äŸïŒ
äžå¿çãªæŠå¿µã¯äŒŒãŠããŸããããšã©ãŒå¢çã®å®è£ ã¯äœ¿çšããŠããããã³ããšã³ããã¬ãŒã ã¯ãŒã¯ã«ãã£ãŠãããã«ç°ãªããŸããããã§ã¯ãã€ã³ã¿ã©ã¯ãã£ããªãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãæ§ç¯ããããã®æãäžè¬çãªãã¬ãŒã ã¯ãŒã¯ã§ããReactã«çŠç¹ãåœãŠãŠã¿ãŸãããã
Reactã®ãšã©ãŒå¢ç
Reactã¯ãšã©ãŒå¢çãäœæããããã®ç¹å®ã®ã¡ã«ããºã ãæäŸããŠããŸãããšã©ãŒå¢çã¯ããã®åã³ã³ããŒãã³ãããªãŒå ã®ã©ããã§çºçããJavaScriptãšã©ãŒãææãããããã®ãšã©ãŒããã°ã«èšé²ããã¢ããªã±ãŒã·ã§ã³å šäœãã¯ã©ãã·ã¥ããã代ããã«ãã©ãŒã«ããã¯UIã衚瀺ããReactã³ã³ããŒãã³ãã§ãããšã©ãŒå¢çã¯ãã¬ã³ããªã³ã°äžãã©ã€ããµã€ã¯ã«ã¡ãœãããããã³ãã¹ãŠã®åã³ã³ããŒãã³ãã®ã³ã³ã¹ãã©ã¯ã¿ã§çºçãããšã©ãŒãææããŸãã
Reactã§ãšã©ãŒå¢çãäœæããããã®äž»èŠãªã¡ãœããïŒ
- `static getDerivedStateFromError(error)`ïŒ ãã®éçã¡ãœããã¯ãåå«ã³ã³ããŒãã³ãããšã©ãŒãã¹ããŒããåŸã«åŒã³åºãããŸãããšã©ãŒããã©ã¡ãŒã¿ãšããŠåãåããç¶æ ãæŽæ°ããããã®ãªããžã§ã¯ããè¿ãå¿ èŠããããŸããããã¯ããã©ãŒã«ããã¯UIãããªã¬ãŒããããã«`error`ãã©ã°ã`true`ã«èšå®ãããªã©ãç¶æ ãæŽæ°ããããã«äœ¿çšãããŸãã
- `componentDidCatch(error, info)`ïŒ ãã®ã¡ãœããã¯ãåå«ã³ã³ããŒãã³ãã«ãã£ãŠãšã©ãŒãã¹ããŒãããåŸã«åŒã³åºãããŸãããšã©ãŒãšããšã©ãŒãã¹ããŒããã³ã³ããŒãã³ãã«é¢ããæ å ±ãå«ããªããžã§ã¯ããåãåããŸããéåžžããšã©ãŒã®ãã°èšé²ã«äœ¿çšãããŸãããã®ã¡ãœããã¯ãåå«ã³ã³ããŒãã³ãã®ã¬ã³ããªã³ã°äžã«çºçãããšã©ãŒã«å¯ŸããŠã®ã¿åŒã³åºãããŸãã
import React from 'react';
interface Props {
children: React.ReactNode;
}
interface State {
hasError: boolean;
error: Error | null;
}
class ErrorBoundary extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error: Error) {
// Update state so the next render will show the fallback UI.
return { hasError: true, error: error };
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
// You can also log the error to an error reporting service
console.error('Uncaught error:', error, errorInfo);
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return (
<div className="error-boundary">
<h2>Something went wrong.</h2>
<p>We're working on fixing it!</p>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.stack}
</details>
</div>
);
}
return this.props.children;
}
}
export default ErrorBoundary;
ãã®`ErrorBoundary`ã³ã³ããŒãã³ãã¯ããã®åã³ã³ããŒãã³ããã©ããããŸããã©ãããããã³ã³ããŒãã³ãå ã§ãšã©ãŒãã¹ããŒããããšã`getDerivedStateFromError`ã¡ãœãããåŒã³åºãããŠç¶æ ãæŽæ°ãããã³ã³ããŒãã³ãã¯ãã©ãŒã«ããã¯UIã§åã¬ã³ããªã³ã°ãããŸãã`componentDidCatch`ã¡ãœããã¯ãšã©ãŒã®ãã°èšé²ã«äœ¿çšãããŸããErrorBoundaryã䜿çšããã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®äžéšãããã§ã©ããããã ãã§ãïŒ
import ErrorBoundary from './ErrorBoundary';
function App() {
return (
<div>
<ErrorBoundary>
<MyComponentThatMightError />
</ErrorBoundary>
<AnotherComponent />
</div>
);
}
`ErrorBoundary`ã³ã³ããŒãã³ããåé¡ãçºçããå¯èœæ§ã®ããã³ã³ããŒãã³ãã®åšãã«é 眮ããããšã§ããããã®ã³ã³ããŒãã³ããéé¢ãããšã©ãŒãçºçããå Žåã«ãã©ãŒã«ããã¯UIãæäŸããŠãã¢ããªã±ãŒã·ã§ã³å šäœãã¯ã©ãã·ã¥ããã®ãé²ããŸãã
ä»ã®ãã¬ãŒã ã¯ãŒã¯ã«ããããšã©ãŒå¢çïŒæŠå¿µïŒ
å®è£ ã®è©³çްã¯ç°ãªããŸããããšã©ãŒå¢çã®äžå¿çãªååã¯AngularãVue.jsã®ãããªä»ã®ããã³ããšã³ããã¬ãŒã ã¯ãŒã¯ã«ãé©çšã§ããŸããéåžžãåæ§ã®æŠç¥ãçšããŠãããå®çŸããŸãïŒ
- AngularïŒ ã³ã³ããŒãã³ãã®ãšã©ãŒãã³ããªã³ã°ãã«ã¹ã¿ã ãšã©ãŒãã³ãã©ãããã³ã€ã³ã¿ãŒã»ãã¿ã䜿çšããŸããAngularã®`ErrorHandler`ã¯ã©ã¹ãå©çšããåé¡ãçºçããå¯èœæ§ã®ããã³ã³ããŒãã³ãããšã©ãŒãã³ããªã³ã°ããžãã¯ã§ã©ããããããšãæ€èšããŠãã ããã
- Vue.jsïŒ ã³ã³ããŒãã³ãå ã§`try...catch`ãããã¯ã䜿çšãããã`Vue.config.errorHandler`ãä»ããŠç»é²ãããã°ããŒãã«ãšã©ãŒãã³ãã©ã䜿çšããŸããVueã«ã¯ãReactã®ãšã©ãŒå¢çã«äŒŒãã³ã³ããŒãã³ãã¬ãã«ã®ãšã©ãŒãã³ããªã³ã°æ©èœããããŸãã
ãšã©ãŒå¢çãšãšã©ãŒãã³ããªã³ã°ã®ãã¹ããã©ã¯ãã£ã¹
ãšã©ãŒå¢çãšãšã©ãŒãã³ããªã³ã°åãã¿ãŒã³ã广çã«å©çšããããã«ã以äžã®ãã¹ããã©ã¯ãã£ã¹ãèæ ®ããŠãã ããïŒ
- ãšã©ãŒãçºçããããã³ãŒããéé¢ããïŒ ãšã©ãŒãã¹ããŒããå¯èœæ§ãé«ãã³ã³ããŒãã³ããã³ãŒãã»ã¯ã·ã§ã³ãããšã©ãŒå¢çãé©åãªãšã©ãŒãã³ããªã³ã°æ§é ã§ã©ããããŸãã
- æç¢ºãªãšã©ãŒã¡ãã»ãŒãžãæäŸããïŒ ãŠãŒã¶ãŒã«ã³ã³ããã¹ããšã¬ã€ãã³ã¹ãæäŸããããŠãŒã¶ãŒãã¬ã³ããªãŒãªãšã©ãŒã¡ãã»ãŒãžãèšèšããŸããäžå¯è§£ãªæè¡çšèªã¯é¿ããŠãã ããã
- 广çã«ãšã©ãŒããã°ã«èšé²ããïŒ ãšã©ãŒã远跡ããé¢é£æ å ±ïŒã¹ã¿ãã¯ãã¬ãŒã¹ããŠãŒã¶ãŒã³ã³ããã¹ããªã©ïŒãåéãããããã°ã容æã«ããããã®å ç¢ãªãšã©ãŒãã®ã³ã°ã·ã¹ãã ãå®è£ ããŸããæ¬çªç°å¢ã§ã¯SentryãBugsnagãRollbarãªã©ã®ãµãŒãã¹ã䜿çšããŸãã
- ãã©ãŒã«ããã¯UIãå®è£ ããïŒ ãšã©ãŒãé©åã«åŠçããã¢ããªã±ãŒã·ã§ã³å šäœãã¯ã©ãã·ã¥ããã®ãé²ããæå³ã®ãããã©ãŒã«ããã¯UIãæäŸããŸãããã©ãŒã«ããã¯ã¯ãäœãèµ·ãã£ããããŠãŒã¶ãŒã«äŒããå¿ èŠã§ããã°å®è¡å¯èœãªã¢ã¯ã·ã§ã³ãææ¡ãã¹ãã§ãã
- ã«ã¹ã¿ã ãšã©ãŒã¯ã©ã¹ã䜿çšããïŒ ç°ãªãã¿ã€ãã®ãšã©ãŒã衚ãããã广çãªãšã©ãŒãã³ããªã³ã°ã®ããã«è¿œå ã®ã³ã³ããã¹ããšæ å ±ã远å ããã«ã¹ã¿ã ãšã©ãŒã¯ã©ã¹ãäœæããŸãã
- ãšã©ãŒå¢çã®ã¹ã³ãŒããèæ ®ããïŒ ã¢ããªã±ãŒã·ã§ã³å šäœãåäžã®ãšã©ãŒå¢çã§ã©ããããªãã§ãã ãããããã¯æ ¹æ¬çãªåé¡ãé ããŠããŸãå¯èœæ§ããããŸãã代ããã«ãã³ã³ããŒãã³ããã¢ããªã±ãŒã·ã§ã³ã®éšåã®åšãã«æŠç¥çã«ãšã©ãŒå¢çãé 眮ããŸãã
- ãšã©ãŒãã³ããªã³ã°ããã¹ãããïŒ ãŠããããã¹ããšçµ±åãã¹ããäœæããŠããšã©ãŒãã³ããªã³ã°ããžãã¯ãæåŸ éãã«æ©èœãããã©ãŒã«ããã¯UIãæ£ãã衚瀺ãããããšã確èªããŸãããšã©ãŒãçºçããå¯èœæ§ã®ããã·ããªãªããã¹ãããŸãã
- ãšã©ãŒãç£èŠã»åæããïŒ ã¢ããªã±ãŒã·ã§ã³ã®ãšã©ãŒãã°ã宿çã«ç£èŠããŠãç¹°ãè¿ãçºçããåé¡ãç¹å®ãããšã©ãŒã®åŸåã远跡ããæ¹åã®äœå°ãããé åãç¹å®ããŸãã
- ããŒã¿æ€èšŒã«åªããïŒ å€éšãœãŒã¹ããåãåã£ãããŒã¿ãæ€èšŒããäžæ£ãªããŒã¿åœ¢åŒã«ããäºæãã¬ãšã©ãŒãé²ããŸãã
- Promiseãšéåææäœãæ éã«æ±ãïŒ `.catch()`ãããã¯ãé©åãªãšã©ãŒãã³ããªã³ã°ã¡ã«ããºã ã䜿çšããŠãéåææäœã§çºçããå¯èœæ§ã®ãããšã©ãŒã確å®ã«åŠçããŸãã
å®äžçã®äŸãšåœéåã«é¢ããèæ ®äºé
ãšã©ãŒå¢çãšãšã©ãŒãã³ããªã³ã°åãã¿ãŒã³ããåœéåãèæ ®ããªããå®äžçã®ã·ããªãªã§ã©ã®ããã«é©çšã§ããããããã€ãã®å®è·µçãªäŸãæ¢ã£ãŠã¿ãŸãããïŒ
äŸïŒEã³ããŒã¹ã¢ããªã±ãŒã·ã§ã³ïŒããŒã¿ååŸïŒ
ååãªã¹ãã衚瀺ããEã³ããŒã¹ã¢ããªã±ãŒã·ã§ã³ãæ³åããŠã¿ãŠãã ãããã¢ããªã±ãŒã·ã§ã³ã¯ããã¯ãšã³ãAPIããååããŒã¿ãååŸããŸãããšã©ãŒå¢çã¯ãAPIåŒã³åºãã«é¢ããæœåšçãªåé¡ãåŠçããããã«äœ¿çšãããŸãã
interface Product {
id: number;
name: string;
price: number;
currency: string;
// ... other product details
}
class ProductList extends React.Component<{}, { products: Product[] | null; loading: boolean; error: Error | null }> {
state = { products: null, loading: true, error: null };
async componentDidMount() {
try {
const products = await this.fetchProducts();
this.setState({ products, loading: false });
} catch (error: any) {
this.setState({ error, loading: false });
}
}
async fetchProducts(): Promise<Product[]> {
const response = await fetch('/api/products'); // API endpoint
if (!response.ok) {
throw new Error(`Failed to fetch products: ${response.status}`);
}
return await response.json();
}
render() {
const { products, loading, error } = this.state;
if (loading) {
return <div>Loading products...</div>;
}
if (error) {
return (
<div className="error-message">
<p>Sorry, we're having trouble loading the products.</p>
<p>Please try again later.</p>
<p>Error details: {error.message}</p> {/* Log the error message for debugging */}
</div>
);
}
return (
<ul>
{products && products.map(product => (
<li key={product.id}>{product.name} - {product.price} {product.currency}</li>
))}
</ul>
);
}
}
// Error Boundary (React Component)
class ProductListErrorBoundary extends React.Component<{children: React.ReactNode}, {hasError: boolean, error: Error | null}> {
constructor(props: any) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error: Error) {
// Update state so the next render will show the fallback UI.
return { hasError: true, error: error };
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
// You can also log the error to an error reporting service
console.error('Product List Error:', error, errorInfo);
}
render() {
if (this.state.hasError) {
// Render a fallback UI (e.g., error message, retry button)
return (
<div className="product-list-error">
<h2>Oops, something went wrong!</h2>
<p>We are unable to load product information at this time.</p>
<button onClick={() => window.location.reload()} >Retry</button>
</div>
);
}
return this.props.children;
}
}
// Usage
function App() {
return (
<div>
<ProductListErrorBoundary>
<ProductList />
</ProductListErrorBoundary>
</div>
);
}
ãã®äŸã§ã¯ïŒ
- `ProductList`ã¯ååããŒã¿ãååŸããŸããã³ã³ããŒãã³ãå ã§ããŒãã£ã³ã°ç¶æ ãæåããååããŒã¿ãããã³ãšã©ãŒç¶æ ãåŠçããŸãã
- `ProductListErrorBoundary`ã¯`ProductList`ã³ã³ããŒãã³ããã©ããããŠãã¬ã³ããªã³ã°äžãAPIåŒã³åºãäžã®ãšã©ãŒãææããããã«äœ¿çšãããŸãã
- APIãªã¯ãšã¹ãã倱æããå Žåã`ProductListErrorBoundary`ã¯UIãã¯ã©ãã·ã¥ããã代ããã«ãŠãŒã¶ãŒãã¬ã³ããªãŒãªãšã©ãŒã¡ãã»ãŒãžãã¬ã³ããªã³ã°ããŸãã
- ãšã©ãŒã¡ãã»ãŒãžã¯ããŠãŒã¶ãŒãåèªã¿èŸŒã¿ã§ãããå詊è¡ããªãã·ã§ã³ãæäŸããŸãã
- ååããŒã¿ã®`currency`ãã£ãŒã«ãã¯ãåœéåã©ã€ãã©ãªïŒäŸïŒJavaScriptã®IntlïŒã䜿çšããŠæ£ãã衚瀺ã§ããŸããããã«ããããŠãŒã¶ãŒã®ãã±ãŒã«èšå®ã«å¿ããŠé貚ããã©ãŒããããããŸãã
äŸïŒåœéçãªãã©ãŒã ããªããŒã·ã§ã³
äœææ å ±ãå«ããŠãŒã¶ãŒããŒã¿ãåéãããã©ãŒã ãèããŠã¿ãŸããããç¹ã«ãç°ãªãäœæåœ¢åŒãæã€ããŸããŸãªåœã®ãŠãŒã¶ãŒãæ±ãå Žåãé©åãªããªããŒã·ã§ã³ãäžå¯æ¬ ã§ãã
// Assume a simplified address interface
interface Address {
street: string;
city: string;
postalCode: string;
country: string;
}
class AddressForm extends React.Component<{}, { address: Address; errors: { [key: string]: string } }> {
state = {
address: {
street: '',
city: '',
postalCode: '',
country: 'US', // Default country
},
errors: {},
};
handleChange = (event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const { name, value } = event.target;
this.setState((prevState) => ({
address: {
...prevState.address,
[name]: value,
},
errors: {
...prevState.errors,
[name]: '', // Clear any previous errors for this field
},
}));
};
handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const { address } = this.state;
const errors = this.validateAddress(address);
if (Object.keys(errors).length > 0) {
this.setState({ errors });
}
else {
// Submit the form (e.g., to an API)
alert('Form submitted!'); // Replace with actual submission logic
}
};
validateAddress = (address: Address) => {
const errors: { [key: string]: string } = {};
// Validation rules based on the selected country
if (!address.street) {
errors.street = 'Street address is required';
}
if (!address.city) {
errors.city = 'City is required';
}
// Example: postal code validation based on the country
switch (address.country) {
case 'US':
if (!/^[0-9]{5}(?:-[0-9]{4})?$/.test(address.postalCode)) {
errors.postalCode = 'Invalid US postal code';
}
break;
case 'CA':
if (!/^[A-Za-z][0-9][A-Za-z][ ]?[0-9][A-Za-z][0-9]$/.test(address.postalCode)) {
errors.postalCode = 'Invalid Canadian postal code';
}
break;
// Add more countries and validation rules
default:
if (!address.postalCode) {
errors.postalCode = 'Postal code is required';
}
break;
}
return errors;
};
render() {
const { address, errors } = this.state;
return (
<form onSubmit={this.handleSubmit}>
<label htmlFor="street">Street:</label>
<input
type="text"
id="street"
name="street"
value={address.street}
onChange={this.handleChange}
/>
{errors.street && <div className="error">{errors.street}</div>}
<label htmlFor="city">City:</label>
<input
type="text"
id="city"
name="city"
value={address.city}
onChange={this.handleChange}
/>
{errors.city && <div className="error">{errors.city}</div>}
<label htmlFor="postalCode">Postal Code:</label>
<input
type="text"
id="postalCode"
name="postalCode"
value={address.postalCode}
onChange={this.handleChange}
/>
{errors.postalCode && <div className="error">{errors.postalCode}</div>}
<label htmlFor="country">Country:</label>
<select
id="country"
name="country"
value={address.country}
onChange={this.handleChange}
>
<option value="US">United States</option>
<option value="CA">Canada</option>
<!-- Add more countries -->
</select>
<button type="submit">Submit</button>
</form>
);
}
}
ãã®äŸã§ã¯ïŒ
- `AddressForm`ã³ã³ããŒãã³ãã¯ãã©ãŒã ããŒã¿ãšããªããŒã·ã§ã³ããžãã¯ã管çããŸãã
- `validateAddress`颿°ã¯ãéžæãããåœã«åºã¥ããŠããªããŒã·ã§ã³ãå®è¡ããŸãã
- åœåºæã®éµäŸ¿çªå·ããªããŒã·ã§ã³ã«ãŒã«ãé©çšãããŸãïŒç±³åœãšã«ããã瀺ãããŠããŸãïŒã
- ã¢ããªã±ãŒã·ã§ã³ã¯ãã±ãŒã«ã«å¿ãããã©ãŒãããã®ããã«`Intl` APIãå©çšããŸããããã¯ãçŸåšã®ãŠãŒã¶ãŒã®ãã±ãŒã«ã«å¿ããŠæ°å€ãæ¥ä»ãé貚ãåçã«ãã©ãŒãããããããã«äœ¿çšãããŸãã
- ãšã©ãŒã¡ãã»ãŒãžã¯ãã°ããŒãã«ã§ããè¯ããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæäŸããããã«ç¿»èš³ããããšãã§ããŸãã
- ãã®ã¢ãããŒãã«ããããŠãŒã¶ãŒã¯å Žæã«é¢ä¿ãªãããŠãŒã¶ãŒãã¬ã³ããªãŒãªæ¹æ³ã§ãã©ãŒã ãèšå ¥ã§ããŸãã
åœéåã®ãã¹ããã©ã¯ãã£ã¹ïŒ
- ããŒã«ã©ã€ãŒãŒã·ã§ã³ã©ã€ãã©ãªã䜿çšããïŒ i18nextãreact-intlãLinguiJSã®ãããªã©ã€ãã©ãªã¯ããŠãŒã¶ãŒã®ãã±ãŒã«ã«åºã¥ããŠããã¹ãã翻蚳ããæ¥ä»ãæ°å€ãé貚ããã©ãŒãããããæ©èœãæäŸããŸãã
- ãã±ãŒã«éžæãæäŸããïŒ ãŠãŒã¶ãŒã奜ã¿ã®èšèªãšå°åãéžæã§ããããã«ããŸããããã¯ãããããããŠã³ãèšå®ããŸãã¯ãã©ãŠã¶èšå®ã«åºã¥ãèªåæ€åºã«ãã£ãŠè¡ãããšãã§ããŸãã
- æ¥ä»ãæå»ãæ°å€ã®åœ¢åŒãåŠçããïŒ `Intl` APIã䜿çšããŠãç°ãªããã±ãŒã«ã«å¯ŸããŠæ¥ä»ãæå»ãæ°å€ãé貚ãé©åã«ãã©ãŒãããããŸãã
- ããã¹ãã®æ¹åãèæ ®ããïŒ UIãå·Šããå³ïŒLTRïŒãšå³ããå·ŠïŒRTLïŒã®äž¡æ¹ã®ããã¹ãæ¹åããµããŒãããããã«èšèšããŸããRTLãµããŒããæ¯æŽããã©ã€ãã©ãªãååšããŸãã
- æåçãªéããèæ ®ããïŒ UIããšã©ãŒã¡ãã»ãŒãžãèšèšããéã«ã¯ãæåçãªèŠç¯ã«æ³šæãæããŸããç¹å®ã®æåã§äžå¿«ãŸãã¯äžé©åãšèŠãªãããå¯èœæ§ã®ããèšèãç»åã®äœ¿çšã¯é¿ããŠãã ããã
- ç°ãªããã±ãŒã«ã§ãã¹ãããïŒ ç¿»èš³ãšãã©ãŒããããæ£ããæ©èœããUIãé©åã«è¡šç€ºãããããšã確èªããããã«ãããŸããŸãªãã±ãŒã«ã§ã¢ããªã±ãŒã·ã§ã³ã培åºçã«ãã¹ãããŸãã
çµè«
TypeScriptã®ãšã©ãŒå¢çãšå¹æçãªãšã©ãŒãã³ããªã³ã°åãã¿ãŒã³ã¯ãä¿¡é Œæ§ãé«ããŠãŒã¶ãŒãã¬ã³ããªãŒãªã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®äžå¯æ¬ ãªèŠçŽ ã§ãããããã®å®è·µæ¹æ³ãå®è£ ããããšã§ãäºæãã¬ã¯ã©ãã·ã¥ãé²ãããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãåäžããããããã°ãšã¡ã³ããã³ã¹ã®ããã»ã¹ãåçåããããšãã§ããŸããåºæ¬çãª`try-catch`ãããã¯ãããããæŽç·Žããã`Result`åãã«ã¹ã¿ã ãšã©ãŒã¯ã©ã¹ãŸã§ããããã®ãã¿ãŒã³ã¯ãå®äžçã®èª²é¡ã«èãããå ç¢ãªã¢ããªã±ãŒã·ã§ã³ãäœæããåãäžããŠãããŸãããããã®ãã¯ããã¯ãåãå ¥ããããšã§ãããè¯ãTypeScriptã³ãŒããæžããã°ããŒãã«ãªãŠãŒã¶ãŒã«ããè¯ãäœéšãæäŸã§ããã§ãããã
ãããžã§ã¯ãã®ããŒãºãšã¢ããªã±ãŒã·ã§ã³ã®è€éãã«æãé©ãããšã©ãŒãã³ããªã³ã°ãã¿ãŒã³ãéžæããããšãå¿ããªãã§ãã ãããåžžã«ãæœåšçãªåé¡ããŠãŒã¶ãŒã«æ¡å ããæç¢ºã§æçãªãšã©ãŒã¡ãã»ãŒãžãšãã©ãŒã«ããã¯UIãæäŸããããšã«çŠç¹ãåœãŠãŠãã ããããããã®ã¬ã€ãã©ã€ã³ã«åŸãããšã§ãããå埩åããããä¿å®æ§ãé«ããæçµçã«ã¯ã°ããŒãã«åžå Žã§æåããã¢ããªã±ãŒã·ã§ã³ãäœæã§ããŸãã
ãããã®ãã¿ãŒã³ãšãã¯ããã¯ãããªãã®ãããžã§ã¯ãã§è©Šããã¢ããªã±ãŒã·ã§ã³ã®ç¹å®ã®èŠä»¶ã«åãããŠé©å¿ãããããšãæ€èšããŠãã ããããã®ã¢ãããŒãã¯ãããè¯ãã³ãŒãå質ãšãã¹ãŠã®ãŠãŒã¶ãŒã«ãšã£ãŠããè¯å®çãªäœéšã«è²¢ç®ããŸãã