TypeScriptãåå®å šæ§ãå°å ¥ããããŒã¿çµ±åãœãªã¥ãŒã·ã§ã³ã匷åãã°ããŒãã«ãªãŠãŒã¶ãŒã«åããŠãããä¿¡é Œæ§ãé«ããä¿å®æ§ãé«ããã¹ã±ãŒã©ãã«ãªãœãªã¥ãŒã·ã§ã³ãæäŸããŸãã
TypeScript ETLããã»ã¹: ã¿ã€ãå®å šæ§ã«ããããŒã¿çµ±åã®åäž
仿¥ã®ããŒã¿é§åå瀟äŒã«ãããŠãç°çš®ãœãŒã¹ããã®ããŒã¿ãå¹ççãã€ç¢ºå®ã«çµ±åããèœåã¯æéèŠèª²é¡ã§ããExtract, Transform, Load (ETL) ããã»ã¹ã¯ããã®çµ±åã®åºç€ã圢æããçµç¹ãåæãã¬ããŒãäœæãããã³ããŸããŸãªããžãã¹ã¢ããªã±ãŒã·ã§ã³ã®ããã«ããŒã¿ãçµ±åãã¯ã¬ã³ãžã³ã°ãæºåããããšãå¯èœã«ããŸããåŸæ¥ã® ETL ããŒã«ãã¹ã¯ãªããã¯ç®çãæãããŠããŸããããJavaScript ããŒã¹ã®ç°å¢ã«åºæã®åçæ§ã¯ãå€ãã®å Žåãå®è¡æãšã©ãŒãäºæããªãããŒã¿ã®äžäžèŽãããã³è€éãªããŒã¿ãã€ãã©ã€ã³ã®ä¿å®ã«ããã課é¡ã«ã€ãªããå¯èœæ§ããããŸããããã§ãéçåä»ãããããã JavaScript ã®ã¹ãŒããŒã»ããã§ãã TypeScript ãç»å ŽããETL ããã»ã¹ã®ä¿¡é Œæ§ãšä¿å®æ§ãåäžãããããã®åŒ·åãªãœãªã¥ãŒã·ã§ã³ãæäŸããŸãã
åçç°å¢ã«ãããåŸæ¥ã® ETL ã®èª²é¡
åŸæ¥ã® ETL ããã»ã¹ãç¹ã«ãã¬ãŒã³ JavaScript ãŸãã¯åçèšèªã§æ§ç¯ããããã®ã¯ãäžé£ã®äžè¬çãªèª²é¡ã«çŽé¢ããããšããããããŸãã
- å®è¡æãšã©ãŒ: éçåãã§ãã¯ããªããããããŒã¿æ§é ãæåŸ ãããå€ããŸãã¯é¢æ°ã·ã°ããã£ã«é¢é£ãããšã©ãŒã¯ãå€ãã®å ŽåãããŒã¿ãåŠçãããåŸããŸãã¯ã¿ãŒã²ããã·ã¹ãã ã«ã€ã³ãžã§ã¹ããããåŸã«ã®ã¿è¡šé¢åããå¯èœæ§ããããŸããããã¯ãé倧ãªãããã°ãªãŒããŒããããšæœåšçãªããŒã¿ç Žæã«ã€ãªããå¯èœæ§ããããŸãã
- ä¿å®æ§ã®è€éã: ETL ãã€ãã©ã€ã³ãè€éããå¢ããããŒã¿ãœãŒã¹ã®æ°ãå¢ãããšãæ¢åã®ã³ãŒããçè§£ããŠå€æŽããããšããŸããŸãå°é£ã«ãªããŸããæç€ºçãªåå®çŸ©ããªããšãéçºè ã¯ãã€ãã©ã€ã³ã®ããŸããŸãªæ®µéã§ããŒã¿ã®äºæ³ããã圢ç¶ãææ¡ããã®ã«èŠåŽãã倿Žäžã«ãšã©ãŒãçºçããå¯èœæ§ããããŸãã
- éçºè ã®ãªã³ããŒãã£ã³ã°: åçèšèªã§æ§ç¯ããããããžã§ã¯ãã«åå ããæ°ããããŒã ã¡ã³ããŒã¯ãæ¥ãªåŠç¿æ²ç·ã«çŽé¢ããå¯èœæ§ããããŸããããŒã¿æ§é ã®æç¢ºãªä»æ§ããªãå Žåãå€ãã®å Žåãåºç¯ãªã³ãŒããèªãã ããå€ããªã£ããäžå®å šãªããã¥ã¡ã³ãã«é Œã£ããããŠãåãæšæž¬ããå¿ èŠããããŸãã
- ã¹ã±ãŒã©ããªãã£ã«é¢ããæžå¿µ: JavaScriptãšãã®ãšã³ã·ã¹ãã ã¯é«åºŠã«ã¹ã±ãŒã©ãã«ã§ãããåå®å šæ§ã®æ¬ åŠã¯ãETL ããã»ã¹ã確å®ã«ã¹ã±ãŒãªã³ã°ããèœåã劚ããå¯èœæ§ããããŸããäºæããªãåé¢é£ã®åé¡ã¯ããã«ããã¯ã«ãªããããŒã¿éã®å¢å ã«äŒŽãããã©ãŒãã³ã¹ãšå®å®æ§ã«åœ±é¿ãäžããå¯èœæ§ããããŸãã
- ã¯ãã¹ããŒã ã³ã©ãã¬ãŒã·ã§ã³: ç°ãªãããŒã ãŸãã¯éçºè ã ETL ããã»ã¹ã«è²¢ç®ããå ŽåãããŒã¿æ§é ãŸãã¯æåŸ ãããåºåã®èª€è§£ã¯ãçµ±åã®åé¡ã«ã€ãªããå¯èœæ§ããããŸããéçåä»ãã¯ãããŒã¿äº€æã®ããã®å ±éèšèªãšå¥çŽãæäŸããŸãã
TypeScript ãšã¯äœãããªã ETL ã«é¢é£ããã®ãïŒ
TypeScript ã¯ãMicrosoft ã«ãã£ãŠéçºããã JavaScript ãåºç€ãšãããªãŒãã³ãœãŒã¹èšèªã§ãããã®äž»ãªé©æ°ã¯ãéçåä»ã ã®è¿œå ã§ããããã¯ãéçºè ã倿°ã颿°ãã©ã¡ãŒã¿ãŒãæ»ãå€ãããã³ãªããžã§ã¯ãæ§é ã®åãæç€ºçã«å®çŸ©ã§ããããšãæå³ããŸããæ¬¡ã«ãTypeScript ã³ã³ãã€ã©ãŒã¯ãéçºäžã«ãããã®åããã§ãã¯ããã³ãŒããå®è¡ãããåã«æœåšçãªãšã©ãŒããã£ããããŸããETL ã«ç¹ã«åœ¹ç«ã€ TypeScript ã®äž»ãªæ©èœã¯æ¬¡ã®ãšããã§ãã
- éçåä»ã: ããŒã¿ã®åãå®çŸ©ããã³é©çšããæ©èœã
- ã€ã³ã¿ãŒãã§ãŒã¹ãšå: ETL ãã€ãã©ã€ã³å šäœã§äžè²«æ§ã確ä¿ããªãããããŒã¿ãªããžã§ã¯ãã®åœ¢ç¶ãå®çŸ©ããããã®åŒ·åãªæ§æèŠçŽ ã
- ã¯ã©ã¹ãšã¢ãžã¥ãŒã«: ã³ãŒããåå©çšå¯èœã§ä¿å®å¯èœãªã³ã³ããŒãã³ãã«æŽçããããã
- ããŒã«ãµããŒã: IDE ãšã®åªããçµ±åã«ããããªãŒãã³ã³ããªãŒãããªãã¡ã¯ã¿ãªã³ã°ãã€ã³ã©ã€ã³ãšã©ãŒå ±åãªã©ã®æ©èœãæäŸãããŸãã
ETL ããã»ã¹ã®å ŽåãTypeScript ã¯ãããå ç¢ã§äºæž¬å¯èœã§ãéçºè ãã¬ã³ããªãŒãªããŒã¿çµ±åãœãªã¥ãŒã·ã§ã³ãæ§ç¯ããæ¹æ³ãæäŸããŸããåå®å šæ§ãå°å ¥ããããšã«ãããç¹ã« Node.js ã®ãããªææ°ã®ããã¯ãšã³ããã¬ãŒã ã¯ãŒã¯ãæäœããå Žåã«ãããŒã¿ã®æœåºã倿ãããã³ããŒãã®æ¹æ³ãå€é©ããŸãã
ETL段éã§ã® TypeScript ã®æŽ»çš
ETL ããã»ã¹ã®åãã§ãŒãºã« TypeScript ãã©ã®ããã«é©çšã§ãããã説æããŸãããã
1. ã¿ã€ãå®å šæ§ã«ããæœåº (E)
æœåºãã§ãŒãºã«ã¯ãããŒã¿ããŒã¹ (SQLãNoSQL)ãAPIããã©ãããã¡ã€ã« (CSVãJSONãXML)ããŸãã¯ã¡ãã»ãŒãžãã¥ãŒãªã©ãããŸããŸãªãœãŒã¹ããããŒã¿ã®ååŸãå«ãŸããŸããTypeScript ç°å¢ã§ã¯ãåãœãŒã¹ããã®ããŒã¿ã®æåŸ ãããæ§é ã衚ãã€ã³ã¿ãŒãã§ãŒã¹ãå®çŸ©ã§ããŸãã
äŸ: REST API ããã®ããŒã¿ã®æœåº
å€éš API ãããŠãŒã¶ãŒããŒã¿ãæœåºãããšããŸããTypeScript ãªãã§ã¯ãJSON ãªããžã§ã¯ããåãåãããã®ããããã£ãçŽæ¥æäœããAPI ã¬ã¹ãã³ã¹æ§é ãäºæãã倿Žãããå Žåã`undefined` ãšã©ãŒãçºçãããªã¹ã¯ããããŸãã
TypeScript ãªã (ãã¬ãŒã³ JavaScript):
```javascript async function fetchUsers(apiEndpoint) { const response = await fetch(apiEndpoint); const data = await response.json(); // data.users ãé åã§ãªãå ŽåããŸãã¯ãŠãŒã¶ãŒãªããžã§ã¯ãã« // 'id' ã 'email' ãªã©ã®ããããã£ããªãå Žåã®ãšã©ãŒã®å¯èœæ§ return data.users.map(user => ({ userId: user.id, userEmail: user.email })); } ```TypeScript ã䜿çš:
ãŸããæåŸ ãããããŒã¿æ§é ã®ã€ã³ã¿ãŒãã§ãŒã¹ãå®çŸ©ããŸãã
```typescript interface ApiUser { id: number; name: string; email: string; // ä»ã®ããããã£ãååšããå¯èœæ§ããããŸãããä»ã¯ãããã®ã¿ã«é¢å¿ããããŸã } interface ApiResponse { users: ApiUser[]; // API ããã®ãã®ä»ã®ã¡ã¿ããŒã¿ } async function fetchUsersTyped(apiEndpoint: string): Promiseå©ç¹:
- æ©æãšã©ãŒæ€åº: API ã¬ã¹ãã³ã¹ã `ApiResponse` ã€ã³ã¿ãŒãã§ãŒã¹ããéžè±ããå Žå (äŸ: `users` ããªãããŸã㯠`id` ãæ°å€ã§ã¯ãªãæååã§ãããªã©)ãTypeScript ã¯ã³ã³ãã€ã«äžã«ãã©ã°ãç«ãŠãŸãã
- ã³ãŒãã®æçã: `ApiUser` ããã³ `ApiResponse` ã€ã³ã¿ãŒãã§ãŒã¹ã¯ãæåŸ ãããããŒã¿æ§é ãæç¢ºã«ææžåããŸãã
- ã€ã³ããªãžã§ã³ããªãªãŒãã³ã³ããªãŒã: IDE ã¯ã`user.id` ã `user.email` ãªã©ã®ããããã£ãžã®ã¢ã¯ã»ã¹ã«é¢ããæ£ç¢ºãªææ¡ãæäŸã§ããŸãã
äŸ: ããŒã¿ããŒã¹ããã®æœåº
SQL ããŒã¿ããŒã¹ããããŒã¿ãæœåºããå ŽåãORM ãŸãã¯ããŒã¿ããŒã¹ãã©ã€ããŒã䜿çšããå ŽåããããŸããTypeScript ã¯ãããŒã¿ããŒã¹ããŒãã«ã®ã¹ããŒããå®çŸ©ã§ããŸãã
```typescript interface DbProduct { productId: string; productName: string; price: number; inStock: boolean; } async function getProductsFromDb(): Promiseããã«ããã`products` ããŒãã«ããååŸããããŒã¿ã«ãå®çŸ©ãããåãæã€ãããã®ç¹å®ã®ãã£ãŒã«ãã確å®ã«å«ãŸããŸãã
2. ã¿ã€ãå®å šæ§ã«ãã倿 (T)
倿ãã§ãŒãºã¯ãã¿ãŒã²ããã·ã¹ãã ã®èŠä»¶ãæºããããã«ãããŒã¿ã®ã¯ã¬ã³ãžã³ã°ããšã³ãªãããéèšãããã³å圢æãè¡ãããå Žæã§ããããã¯ãå€ãã®å ŽåãETL ããã»ã¹ã®æãè€éãªéšåã§ãããåå®å šæ§ãéåžžã«éèŠã§ããããšã蚌æãããŠããŸãã
äŸ: ããŒã¿ã¯ã¬ã³ãžã³ã°ãšãšã³ãªããã¡ã³ã
æœåºããããŠãŒã¶ãŒããŒã¿ã倿ããå¿ èŠããããšããŸããååããã©ãŒãããããããçå¹Žææ¥ããã®å¹Žéœ¢ãèšç®ããããäœããã®åºæºã«åºã¥ããŠã¹ããŒã¿ã¹ã远å ãããããå¿ èŠãããå ŽåããããŸãã
TypeScript ãªã:
```javascript function transformUsers(users) { return users.map(user => { const fullName = `${user.firstName || ''} ${user.lastName || ''}`.trim(); const age = user.birthDate ? new Date().getFullYear() - new Date(user.birthDate).getFullYear() : null; const status = (user.lastLogin && (new Date() - new Date(user.lastLogin)) < (30 * 24 * 60 * 60 * 1000)) ? 'Active' : 'Inactive'; return { userId: user.id, fullName: fullName, userAge: age, accountStatus: status }; }); } ```ãã® JavaScript ã³ãŒãã§ã¯ã`user.firstName`ã`user.lastName`ã`user.birthDate`ããŸã㯠`user.lastLogin` ãæ¬ èœããŠããããäºæããªãåãæã£ãŠããå Žåã倿ã¯èª€ã£ãçµæãçæãããããšã©ãŒãã¹ããŒãããããå¯èœæ§ããããŸããããšãã°ã`birthDate` ãæå¹ãªæ¥ä»æååã§ãªãå Žåã`new Date(user.birthDate)` ã倱æããå¯èœæ§ããããŸãã
TypeScript ã䜿çš:
倿颿°ã®å ¥åãšåºåã®äž¡æ¹ã®ã€ã³ã¿ãŒãã§ãŒã¹ãå®çŸ©ããŸãã
```typescript interface ExtractedUser { id: number; firstName?: string; // ãªãã·ã§ã³ã®ããããã£ã¯æç€ºçã«ããŒã¯ãããŸã lastName?: string; birthDate?: string; // API ããã®æ¥ä»ã¯æååãšããŠååŸãããããšãæ³å® lastLogin?: string; // API ããã®æ¥ä»ã¯æååãšããŠååŸãããããšãæ³å® } interface TransformedUser { userId: number; fullName: string; userAge: number | null; accountStatus: 'Active' | 'Inactive'; // ç¹å®ã®ç¶æ ã® Union å } function transformUsersTyped(users: ExtractedUser[]): TransformedUser[] { return users.map(user => { const fullName = `${user.firstName || ''} ${user.lastName || ''}`.trim(); let userAge: number | null = null; if (user.birthDate) { const birthYear = new Date(user.birthDate).getFullYear(); const currentYear = new Date().getFullYear(); userAge = currentYear - birthYear; } let accountStatus: 'Active' | 'Inactive' = 'Inactive'; if (user.lastLogin) { const lastLoginTimestamp = new Date(user.lastLogin).getTime(); const thirtyDaysAgo = Date.now() - (30 * 24 * 60 * 60 * 1000); if (lastLoginTimestamp > thirtyDaysAgo) { accountStatus = 'Active'; } } return { userId: user.id, fullName, userAge, accountStatus }; }); } ```å©ç¹:
- ããŒã¿æ€èšŒ: TypeScript ã¯ã`user.firstName`ã`user.lastName` ãªã©ãæååãšããŠæ±ããããããªãã·ã§ã³ã§ããããšã匷å¶ããŸãããŸããæ»ããªããžã§ã¯ãã `TransformedUser` ã€ã³ã¿ãŒãã§ãŒã¹ã«å³å¯ã«æºæ ããŠããããšãä¿èšŒããããããã£ã®èª€ã£ãçç¥ãŸãã¯è¿œå ãé²ããŸãã
- å ç¢ãªæ¥ä»åŠç: `new Date()` ã¯ãç¡å¹ãªæ¥ä»æååã«å¯ŸããŠãšã©ãŒãã¹ããŒããå¯èœæ§ããããŸããã`birthDate` ãš `lastLogin` ã `string` (ãŸã㯠`string | null`) ãšããŠæç€ºçã«å®çŸ©ããããšã«ãããæåŸ ããåãæç¢ºã«ãªããããé©åãªãšã©ãŒåŠçããžãã¯ãå¯èœã«ãªããŸããããé«åºŠãªã·ããªãªã§ã¯ãæ¥ä»ã®ã«ã¹ã¿ã åã¬ãŒããå«ãŸããå ŽåããããŸãã
- Enum ãªã©ã®ç¶æ : `accountStatus` ã« `'Active' | 'Inactive'` ã®ãã㪠Union åã䜿çšãããšãå¯èœãªå€ãå¶éãããã¿ã€ããã¹ãç¡å¹ãªã¹ããŒã¿ã¹ã®å²ãåœãŠãé²ãããšãã§ããŸãã
äŸ: ããŒã¿ã®æ¬ èœãŸãã¯åã®äžäžèŽã®åŠç
å€ãã®å Žåã倿ããžãã¯ã¯ããŒã¿ã®æ¬ èœãé©åã«åŠçããå¿ èŠããããŸããTypeScript ã®ãªãã·ã§ã³ã®ãããã㣠(`?`) ãš Union å (`|`) ã¯ãããã«æé©ã§ãã
```typescript interface SourceRecord { orderId: string; items: Array<{ productId: string; quantity: number; pricePerUnit?: number }>; discountCode?: string; } interface ProcessedOrder { orderIdentifier: string; totalAmount: number; hasDiscount: boolean; } function calculateOrderTotal(record: SourceRecord): ProcessedOrder { let total = 0; for (const item of record.items) { // pricePerUnit ãæ°å€ã§ããããšã確èªããŠããä¹ç®ãã const price = typeof item.pricePerUnit === 'number' ? item.pricePerUnit : 0; total += item.quantity * price; } const hasDiscount = record.discountCode !== undefined; return { orderIdentifier: record.orderId, totalAmount: total, hasDiscount: hasDiscount }; } ```ããã§ã`item.pricePerUnit` ã¯ãªãã·ã§ã³ã§ããããã®åã¯æç€ºçã«ãã§ãã¯ãããŸãã`record.discountCode` ããªãã·ã§ã³ã§ãã`ProcessedOrder` ã€ã³ã¿ãŒãã§ãŒã¹ã¯ãåºåã®åœ¢ç¶ãä¿èšŒããŸãã
3. ã¿ã€ãå®å šæ§ã«ããããŒã (L)
ããŒããã§ãŒãºã«ã¯ã倿ãããããŒã¿ãããŒã¿ãŠã§ã¢ããŠã¹ãããŒã¿ã¬ã€ã¯ãããŒã¿ããŒã¹ããŸãã¯å¥ã® API ãªã©ã®ã¿ãŒã²ããå ã«æžã蟌ãããšãå«ãŸããŸããåå®å šæ§ã«ãããããŒããããããŒã¿ãã¿ãŒã²ããã·ã¹ãã ã®ã¹ããŒãã«æºæ ããŠããããšãä¿èšŒãããŸãã
äŸ: ããŒã¿ãŠã§ã¢ããŠã¹ãžã®ããŒã
倿ããããŠãŒã¶ãŒããŒã¿ããå®çŸ©ãããã¹ããŒããæã€ããŒã¿ãŠã§ã¢ããŠã¹ã®ããŒãã«ã«ããŒãããŠãããšããŸãã
TypeScript ãªã:
```javascript async function loadUsersToWarehouse(users) { for (const user of users) { // ééã£ãããŒã¿åãŸãã¯æ¬ èœããŠããåãæž¡ããªã¹ã¯ await warehouseClient.insert('users_dim', { user_id: user.userId, user_name: user.fullName, age: user.userAge, status: user.accountStatus }); } } ````user.userAge` ã `null` ã§ããŠã§ã¢ããŠã¹ãæŽæ°ãæåŸ ããŠããå ŽåããŸã㯠`user.fullName` ãäºæããæ°å€ã§ããå Žåãæ¿å ¥ã倱æããå¯èœæ§ããããŸããååãããŠã§ã¢ããŠã¹ã®ã¹ããŒããšç°ãªãå Žåããšã©ãŒã®åå ãšãªãå¯èœæ§ããããŸãã
TypeScript ã䜿çš:
ãŠã§ã¢ããŠã¹ã®ããŒãã«ã¹ããŒãã«äžèŽããã€ã³ã¿ãŒãã§ãŒã¹ãå®çŸ©ããŸãã
```typescript interface WarehouseUserDimension { user_id: number; user_name: string; age: number | null; // 幎霢㮠Nullable æŽæ° status: 'Active' | 'Inactive'; } async function loadUsersToWarehouseTyped(users: TransformedUser[]): Promiseå©ç¹:
- ã¹ããŒãã®éµå®: `WarehouseUserDimension` ã€ã³ã¿ãŒãã§ãŒã¹ã¯ããŠã§ã¢ããŠã¹ã«éä¿¡ãããããŒã¿ãæ£ããæ§é ãšåãæã£ãŠããããšãä¿èšŒããŸããéžè±ã¯ãã¹ãŠã³ã³ãã€ã«æã«ãã£ãããããŸãã
- ããŒã¿ããŒããšã©ãŒã®åæž: åã®äžäžèŽã«ãããããŒãããã»ã¹äžã®äºæããªããšã©ãŒãå°ãªããªããŸãã
- æç¢ºãªããŒã¿å¥çŽ: ã€ã³ã¿ãŒãã§ãŒã¹ã¯ã倿ããžãã¯ãšã¿ãŒã²ããããŒã¿ã¢ãã«éã®æç¢ºãªå¥çŽãšããŠæ©èœããŸãã
åºæ¬ç㪠ETL ãè¶ ããŠ: ããŒã¿çµ±åã®ããã®é«åºŠãª TypeScript ãã¿ãŒã³
TypeScript ã®æ©èœã¯åºæ¬çãªå泚éãè¶ ããŠæ¡åŒµãããŠãããETL ããã»ã¹ãå€§å¹ ã«åŒ·åã§ããé«åºŠãªãã¿ãŒã³ãæäŸããŠããŸãã
1. åå©çšæ§ã®ããã®ãžã§ããªãã¯é¢æ°ãšå
ETL ãã€ãã©ã€ã³ã«ã¯ãããŸããŸãªããŒã¿åã«ãããå埩çãªæäœãããå«ãŸããŸãããžã§ããªãã¯ã䜿çšãããšãåå®å šæ§ãç¶æããªãããããŸããŸãªåã§æ©èœãã颿°ãšåãèšè¿°ã§ããŸãã
äŸ: ãžã§ããªãã¯ããŒã¿ããããŒ
```typescript function mapDataãã®ãžã§ããªã㯠`mapData` 颿°ã¯ããããããããã³ã°æäœã«äœ¿çšã§ããå ¥åãšåºåã®åãæ£ããåŠçãããããã«ããŸãã
2. å®è¡ææ€èšŒã®ããã®åã¬ãŒã
TypeScript ã¯ã³ã³ãã€ã«æã®ãã§ãã¯ã«åªããŠããŸãããç¹ã«åä¿¡åãå®å šã«ä¿¡é Œã§ããªãå€éšããŒã¿ãœãŒã¹ãæ±ãå Žåãªã©ãå®è¡æã«ããŒã¿ãæ€èšŒããå¿ èŠãããå ŽåããããŸããåã¬ãŒãã¯ãå®è¡æãã§ãã¯ãå®è¡ããç¹å®ã®ã¹ã³ãŒãå ã®å€æ°ã®åã«ã€ã㊠TypeScript ã³ã³ãã€ã©ãŒã«æç€ºãã颿°ã§ãã
äŸ: å€ãæå¹ãªæ¥ä»æååã§ãããã©ããã®æ€èšŒ
```typescript function isValidDateString(value: any): value is string { if (typeof value !== 'string') { return false; } const date = new Date(value); return !isNaN(date.getTime()); } function processDateValue(dateInput: any): string | null { if (isValidDateString(dateInput)) { // ãã®ãããã¯å ã§ã¯ãTypeScript 㯠dateInput ãæååã§ããããšãèªèããŠããŸã return new Date(dateInput).toISOString(); } else { return null; } } ```ãã® `isValidDateString` åã¬ãŒãã¯ã倿ããžãã¯å ã§äœ¿çšããŠãå€éš API ãŸãã¯ãã¡ã€ã«ããã®æœåšçã«äžæ£ãªæ¥ä»å ¥åãå®å šã«åŠçã§ããŸãã
3. è€éãªããŒã¿æ§é ã®ããã® Union åãšåºå¥ããã Union
å Žåã«ãã£ãŠã¯ãããŒã¿ãè€æ°ã®åœ¢åŒã§è¡šç€ºãããããšããããŸããUnion åã䜿çšãããšã倿°ãç°ãªãåã®å€ãä¿æã§ããŸããåºå¥ããã Union ã¯ãUnion ã®åã¡ã³ããŒããTypeScript ãåãçµã蟌ãããšãå¯èœã«ããå ±éã®ãªãã©ã«ãããã㣠(å€å¥å) ãæã€åŒ·åãªãã¿ãŒã³ã§ãã
äŸ: ç°ãªãã€ãã³ãã¿ã€ãã®åŠç
```typescript interface OrderCreatedEvent { type: 'ORDER_CREATED'; orderId: string; amount: number; } interface OrderShippedEvent { type: 'ORDER_SHIPPED'; orderId: string; shippingDate: string; } type OrderEvent = OrderCreatedEvent | OrderShippedEvent; function processOrderEvent(event: OrderEvent): void { switch (event.type) { case 'ORDER_CREATED': // TypeScript ã¯ããã§ event ã OrderCreatedEvent ã§ããããšãèªèããŠããŸã console.log(`Order ${event.orderId} created with amount ${event.amount}`); break; case 'ORDER_SHIPPED': // TypeScript ã¯ããã§ event ã OrderShippedEvent ã§ããããšãèªèããŠããŸã console.log(`Order ${event.orderId} shipped on ${event.shippingDate}`); break; default: // ãã® 'never' åã¯ããã¹ãŠã®ã±ãŒã¹ãåŠçãããããšãä¿èšŒããã®ã«åœ¹ç«ã¡ãŸã const _exhaustiveCheck: never = event; console.error('Unknown event type:', _exhaustiveCheck); } } ```ãã®ãã¿ãŒã³ã¯ãã¡ãã»ãŒãžãã¥ãŒãŸã㯠Webhook ããã®ã€ãã³ããåŠçããå Žåã«éåžžã«åœ¹ç«ã¡ãåã€ãã³ãã®ç¹å®ã®ããããã£ãæ£ããå®å šã«åŠçãããããã«ããŸãã
é©åãªããŒã«ãšã©ã€ãã©ãªã®éžæ
TypeScript ETL ããã»ã¹ãæ§ç¯ããå Žåãã©ã€ãã©ãªãšãã¬ãŒã ã¯ãŒã¯ã®éžæã¯ãéçºè ãšã¯ã¹ããªãšã³ã¹ãšãã€ãã©ã€ã³ã®å ç¢æ§ã«å€§ãã圱é¿ããŸãã
- Node.js ãšã³ã·ã¹ãã : ãµãŒããŒåŽã® ETL ã®å ŽåãNode.js ãäžè¬çãªéžæè¢ã§ããHTTP ãªã¯ãšã¹ãçšã® `axios`ãããŒã¿ããŒã¹ãã©ã€ã㌠(äŸ: PostgreSQL çšã® `pg`ãMySQL çšã® `mysql2`)ãããã³ ORM (äŸ: TypeORMãPrisma) ãªã©ã®ã©ã€ãã©ãªã¯ãåªãã TypeScript ãµããŒããæäŸããŠããŸãã
- ããŒã¿å€æã©ã€ãã©ãª: `lodash` (ãã® TypeScript å®çŸ©ã䜿çš) ãªã©ã®ã©ã€ãã©ãªã¯ããŠãŒãã£ãªãã£é¢æ°ã«éåžžã«åœ¹ç«ã¡ãŸããããè€éãªããŒã¿æäœã®å Žåã¯ãããŒã¿ã©ã³ã°ãªã³ã°å°çšã«èšèšãããã©ã€ãã©ãªãæ€èšããŠãã ããã
- ã¹ããŒãæ€èšŒã©ã€ãã©ãª: TypeScript ã¯ã³ã³ãã€ã«æã®ãã§ãã¯ãæäŸããŸãããå®è¡æã®æ€èšŒã¯äžå¯æ¬ ã§ãã`zod` ã `io-ts` ãªã©ã®ã©ã€ãã©ãªã¯ãTypeScript ã®éçåä»ããè£å®ããŠãå®è¡æããŒã¿ã¹ããŒããå®çŸ©ããã³æ€èšŒããããã®åŒ·åãªæ¹æ³ãæäŸããŸãã
- ãªãŒã±ã¹ãã¬ãŒã·ã§ã³ããŒã«: è€éãªè€æ°ã¹ãããã® ETL ãã€ãã©ã€ã³ã®å ŽåãApache Airflow ãŸã㯠Prefect (Node.js/TypeScript ãšçµ±åå¯èœ) ãªã©ã®ãªãŒã±ã¹ãã¬ãŒã·ã§ã³ããŒã«ãäžå¯æ¬ ã§ããåå®å šæ§ãããããã®ãªãŒã±ã¹ãã¬ãŒã¿ãŒã®æ§æãšã¹ã¯ãªããã«æ¡åŒµããŸãã
TypeScript ETL ã®ã°ããŒãã«ãªèæ ®äºé
ã°ããŒãã«ãªãŠãŒã¶ãŒåãã« TypeScript ETL ããã»ã¹ãå®è£ ããå Žåãããã€ãã®èŠå ãæ³šææ·±ãæ€èšããå¿ èŠããããŸãã
- ã¿ã€ã ãŸãŒã³: æ¥ææäœã§ãç°ãªãã¿ã€ã ãŸãŒã³ãæ£ããåŠçãããããã«ããŸããã¿ã€ã ã¹ã¿ã³ãã UTC ã§ä¿åãã衚瀺ãŸãã¯ããŒã«ã«åŠççšã«å€æããããšã¯ãäžè¬çãªãã¹ããã©ã¯ãã£ã¹ã§ãã`moment-timezone` ãªã©ã®ã©ã€ãã©ãªãŸãã¯çµã¿èŸŒã¿ã® `Intl` API ã圹ç«ã¡ãŸãã
- é貚ãšããŒã«ãªãŒãŒã·ã§ã³: ããŒã¿ã«éèååŒãŸãã¯ããŒã«ã©ã€ãºãããã³ã³ãã³ããå«ãŸããŠããå Žåã¯ãæ°å€ã®ãã©ãŒããããšé貚ã®è¡šçŸãæ£ããåŠçãããŠããããšã確èªããŸããTypeScript ã€ã³ã¿ãŒãã§ãŒã¹ã¯ãæåŸ ãããé貚ã³ãŒããšç²ŸåºŠãå®çŸ©ã§ããŸãã
- ããŒã¿ãã©ã€ãã·ãŒãšèŠå¶ (äŸ: GDPRãCCPA): ETL ããã»ã¹ã«ã¯ãå€ãã®å Žåãæ©å¯ããŒã¿ãå«ãŸããŸããåå®çŸ©ã¯ãPII (å人ãç¹å®ã§ããæ å ±) ãé©åãªæ³šæãšã¢ã¯ã»ã¹å¶åŸ¡ã§åŠçãããŠããããšã確èªããã®ã«åœ¹ç«ã¡ãŸããæ©å¯ããŒã¿ãã£ãŒã«ããæç¢ºã«åºå¥ããããã«åãèšèšããããšã¯ãæåã®ã¹ããããšããŠæé©ã§ãã
- æåãšã³ã³ãŒãã£ã³ã°: ãã¡ã€ã«ãŸãã¯ããŒã¿ããŒã¹ããèªã¿æžãããå Žåã¯ãæåãšã³ã³ãŒãã£ã³ã° (äŸ: UTF-8) ã«æ³šæããŠãã ãããç¹ã«åœéæåã䜿çšããå Žåã¯ãããŒã¿ãç Žæããªãããã«ãããŒã«ãšæ§æãå¿ é ã®ãšã³ã³ãŒãã£ã³ã°ããµããŒãããŠããããšã確èªããŠãã ããã
- åœéããŒã¿åœ¢åŒ: æ¥ä»åœ¢åŒãæ°å€åœ¢åŒãããã³äœææ§é ã¯ãå°åã«ãã£ãŠå€§å¹ ã«ç°ãªãå ŽåããããŸããTypeScript ã€ã³ã¿ãŒãã§ãŒã¹ã«ãã£ãŠéç¥ããã倿ããžãã¯ã¯ãæåŸ ãããåœé圢åŒã§ããŒã¿ãè§£æããã³çæããã®ã«ååãªæè»æ§ãå¿ èŠã§ãã
TypeScript ETL éçºã®ãã¹ããã©ã¯ãã£ã¹
ETL ããã»ã¹ã« TypeScript ã䜿çšããããšã®ã¡ãªãããæå€§åããã«ã¯ã次ã®ãã¹ããã©ã¯ãã£ã¹ãæ€èšããŠãã ããã
- ãã¹ãŠã®ããŒã¿ã¹ããŒãžã«æç¢ºãªã€ã³ã¿ãŒãã§ãŒã¹ãå®çŸ©ãã: ETL ã¹ã¯ãªããã®ãšã³ããªãã€ã³ããæœåºåŸãå倿ã¹ãããã®åŸãããŒãåã®ããŒã¿ã®åœ¢ç¶ãææžåããŸãã
- äžå€æ§ã®ããã« Readonly åã䜿çšãã: äœæåŸã«å€æŽããŠã¯ãªããªãããŒã¿ã®å Žåã¯ãã€ã³ã¿ãŒãã§ãŒã¹ããããã£ãŸãã¯èªã¿åãå°çšé åã§ `readonly` 修食åã䜿çšããŠãå¶çºçãªãã¥ãŒããŒã·ã§ã³ãé²ããŸãã
- å ç¢ãªãšã©ãŒåŠçãå®è£ ãã: TypeScript ã¯å€ãã®ããšã©ãŒããã£ããããŸãããäºæããªãå®è¡æã®åé¡ãçºçããå¯èœæ§ããããŸãã`try...catch` ãããã¯ã䜿çšãã倱æããæäœãèšé²ããŠå詊è¡ããããã®æŠç¥ãå®è£ ããŸãã
- æ§æç®¡çãæŽ»çšãã: æ¥ç¶æååãAPI ãšã³ããã€ã³ããããã³å€æã«ãŒã«ãæ§æãã¡ã€ã«ã«å€éšåããŸããTypeScript ã€ã³ã¿ãŒãã§ãŒã¹ã䜿çšããŠãæ§æãªããžã§ã¯ãã®æ§é ãå®çŸ©ããŸãã
- ãŠããããã¹ããšçµ±åãã¹ããèšè¿°ãã: 培åºçãªãã¹ããäžå¯æ¬ ã§ããJest ã Mocha with Chai ãªã©ã®ãã¹ããã¬ãŒã ã¯ãŒã¯ã䜿çšãããšããžã±ãŒã¹ããšã©ãŒæ¡ä»¶ãå«ãããŸããŸãªããŒã¿ã·ããªãªãã«ããŒãããã¹ããèšè¿°ããŸãã
- äŸåé¢ä¿ãææ°ã®ç¶æ ã«ä¿ã€: TypeScript èªäœãšãããžã§ã¯ãã®äŸåé¢ä¿ã宿çã«æŽæ°ããŠãææ°ã®æ©èœãããã©ãŒãã³ã¹ã®åäžãããã³ã»ãã¥ãªãã£ãããã®ã¡ãªããã享åããŸãã
- Linting ããã³ãã©ãŒãããããŒã«ãå©çšãã: ESLint (TypeScript ãã©ã°ã€ã³ä»ã) ã Prettier ãªã©ã®ããŒã«ã¯ãã³ãŒãã£ã³ã°æšæºãé©çšããããŒã å šäœã§ã³ãŒãã®äžè²«æ§ãç¶æã§ããŸãã
çµè«
TypeScript ã¯ãç¹ã«åç㪠JavaScript/Node.js ãšã³ã·ã¹ãã å ã§ãETL ããã»ã¹ã«å¿ èŠäžå¯æ¬ ãªäºæž¬å¯èœæ§ãšå ç¢æ§ã®ã¬ã€ã€ãŒããããããŸããéçºè ãã³ã³ãã€ã«æã«ããŒã¿åãå®çŸ©ããŠé©çšã§ããããã«ããããšã§ãTypeScript ã¯å®è¡æãšã©ãŒã®å¯èœæ§ãåçã«æžãããã³ãŒãã®ä¿å®ãç°¡çŽ åããéçºè ã®çç£æ§ãåäžãããŸããäžçäžã®çµç¹ãéèŠãªããžãã¹æ©èœã®ããã«ããŒã¿çµ±åã«åŒãç¶ãäŸåããŠãããããETL ã« TypeScript ãæ¡çšããããšã¯ãããä¿¡é Œæ§ãé«ããã¹ã±ãŒã©ãã«ã§ãä¿å®æ§ã®é«ãããŒã¿ãã€ãã©ã€ã³ã«ã€ãªããæŠç¥çãªåãã§ããåå®å šæ§ã®æ¡çšã¯ãåãªãéçºãã¬ã³ãã§ã¯ãªããã°ããŒãã«ãªèŠèŽè ã«å¹æçã«ãµãŒãã¹ãæäŸã§ããå埩åã®ããããŒã¿ã€ã³ãã©ã¹ãã©ã¯ãã£ãæ§ç¯ããããã®åºæ¬çãªã¹ãããã§ãã