嘿嘿,大家寫 TypeScript 是不是也常常踩雷呢?
其實 TypeScript 超好用,但那種突然冒出來的錯誤訊息,真的會讓人瞬間卡住啊!
不用怕,這篇就是你的救星!
我會帶你一起來破解那些搞得人頭昏腦脹的 TypeScript 錯誤,幫你解鎖各種「我哪有寫錯!」的迷之瞬間!
不管是神出鬼沒的 any
類型、還是奇怪的 never
錯誤,通通包在我身上!
就讓我們輕鬆搞定這些煩人的小bug,讓你的程式碼從此不再鬧脾氣!一起變更強吧~
type Talk = {
title: string,
abstract: string,
speaker: string
}
type TechEventBase = {
title: string,
description: string
date: Date,
capacity: number,
rsvp: number,
kind: EventKind
}
type Conference = TechEventBase & {
location: string,
price: number,
talks: Talk[],
kind: 'conference'
}
type Meetup = TechEventBase & {
location: string,
price: string,
talks: Talk[],
kind: 'meetup'
}
type Webinar = TechEventBase & {
url: string,
price?: number,
talks: Talk,
kind: 'webinar'
}
type TechEvent = Webinar | Conference | Meetup;
type EventKind = 'conference' | 'meetup' | 'webinar'
type UserEvents = {
watching: TechEvent[],
rsvp: TechEvent[],
attended: TechEvent[],
signedout: TechEvent[],
}
type UserEventCategory =
'watching' | 'rsvp' | 'attended' | 'signedoff'
function filterUserEvent(
userEventList: UserEvents,
category: UserEventCategory,
filterKind?: EventKind
) {
const filteredList = userEventList[category]
if (filterKind) {
return filteredList.filter(event =>
event.kind === filterKind)
}
return filteredList
}
function getEventTeaser(event: TechEvent) {
switch(event.kind) {
case 'conference':
return `${event.title} (Conference), ` +
`priced at ${event.price} USD`
case 'meetup':
return `${event.title} (Meetup), ` +
`hosted at ${event.location}`
case 'webinar':
return `${event.title} (Webinar), ` +
`available online at ${event.url}`
case 'hackathon':
return `${event.title} (Hackathon)`
default:
throw new Error('Not sure what to do with that!')
}
}
在這段程式碼中,我們遇到了一些常見的 TypeScript 錯誤。
這些錯誤若不修正,將影響程式的正常運行。
接下來,我將逐步解析每個錯誤的原因、如何解決,並提供修正後的程式碼。
UserEventCategory
類型的表達式無法用於索引類型 UserEvents
,因此元素隱式具有 any
類型。這個錯誤的根本原因是 TypeScript 無法確認 UserEventCategory
中的 category
參數可以安全地索引 UserEvents
。這是因為 UserEventCategory
包含了 'signedoff'
,而 UserEvents
對應的鍵名其實是 'signedout'
。
解決方法:
UserEventCategory
的 'signedoff'
修改為 'signedout'
,確保名稱對應一致。修正後的程式碼:
type UserEventCategory = 'watching' | 'rsvp' | 'attended' | 'signedout';
event
隱式具有 any
類型。在 filterUserEvent
函式中,使用 filter
方法時,TypeScript 無法自動推斷 event
參數的類型,因此會預設為 any
,這樣做容易引發類型安全問題。
解決方法:
filter
方法中的 event
參數類型為 TechEvent
。修正後的程式碼:
function filterUserEvent(
userEventList: UserEvents,
category: UserEventCategory,
filterKind?: EventKind
) {
const filteredList = userEventList[category];
if (filterKind) {
return filteredList.filter((event: TechEvent) =>
event.kind === filterKind);
}
return filteredList;
}
"hackathon"
無法與 "conference" | "meetup" | "webinar"
類型進行比較。這個錯誤出現在 getEventTeaser
函式中的 switch
語句中,因為 'hackathon'
並不在 EventKind
類型定義中,且也未被任何 TechEvent
使用,因此類型不匹配。
解決方法:
switch
語句中的 'hackathon'
,確保處理的類型符合 EventKind
的定義。修正後的程式碼:
function getEventTeaser(event: TechEvent) {
switch(event.kind) {
case 'conference':
return `${event.title} (Conference), ` +
`priced at ${event.price} USD`;
case 'meetup':
return `${event.title} (Meetup), ` +
`hosted at ${event.location}`;
case 'webinar':
return `${event.title} (Webinar), ` +
`available online at ${event.url}`;
default:
throw new Error('Not sure what to do with that!');
}
}
'title'
不存在於 never
類型上。這個錯誤是因為 TypeScript 無法確定 getEventTeaser
中 event
的正確類型,推斷結果為 never
類型。這通常是因為處理了不應該存在的類型(如 'hackathon'
),導致 TypeScript 無法理解 event
的結構。
解決方法:
switch
案例匹配正確定義的類型,這樣就不會出現 never
類型錯誤。索引簽名不匹配:
明確定義類型:
any
,這樣能讓 TypeScript 的類型檢查機制發揮作用,保證程式的安全性和可讀性。Switch 案例的類型匹配:
switch
語句應只處理定義內的有效類型。如果加入未定義的類型,會導致 TypeScript 無法正確推斷類型,引發 never
錯誤。正確處理類型:
透過這些修正,程式碼會更符合 TypeScript 的嚴格類型系統,不僅提升開發體驗,還能在開發過程中及早發現問題,避免潛在的錯誤。
好啦,今天的 TypeScript 除錯小冒險就到這邊啦
希望看完之後,大家在面對那些奇奇怪怪的錯誤訊息時,不再感到手足無措。
別忘了,程式開發就是這樣,一步步踩坑、一步步成長,這才是進步的關鍵!
下次遇到 bug 就別怕了,拿出你的自信和技巧,把它當作練等升級的好機會!
Coding 這條路上,我們都在一起學習、一起變強,未來也會越來越厲害~
加油,寫出屬於自己的神級程式吧!💪🚀✨