目錄
type narrowing
type narrowing指的是盡可能地將型別的範圍縮小
,這可以利於debug
例如'apple'、'tempura'、'Monday'、'Sunday'都是string,但是只有最後兩個是一週中的日子
假設有個function接收一個字串,並判斷其是不是週末字串
正常的情況下,不該傳遞一個不是週一(到日)的字串給isWeekend,因為那樣的話一定會得到false
所以我們可以直接將day的型別限縮到只有Weekday,這樣當不小心傳到Fruit字串的話,在開發時就會發現了
enum Weekday {
MON = 'Monday',
TUE = 'Tuesday',
WED = 'Wednesday',
THU = 'Thursday',
FRI = 'Friday',
SAT = 'Staturday',
SUN = 'Sunday',
}
const isWeekend = (day: Weekday) => {
if([Weekday.SAT, Weekday.SUN].includes(day)){
return true;
}
return false;
}
除了以上的方式以外,type guard、type predicate
,這篇要介紹的extends
,也都是type narrowing
的方法
extends
extends不只能用於擴展interface,還可以限縮型別
在使用泛型時,可以配合extends
來限縮型別範圍,這樣可以讓程式碼保持適中的彈性
// 檢查字串是不是物件的key
export const isKeyOfObject =
<T extends object>(enumObject: T) =>
(value: string): value is Extract<keyof T, string> =>
value in enumObject;
// 檢查字串是不是物件的value
const isValueOfObject = <T extends object>(enumObj: T) => {
return (str:unknown):str is T => {
return Object.values(enumObj).includes(str);
}
}
// 檢查字串是不是物件的value的小寫化
const isObjectLowerCaseValue = <T extends object>(enumObj: T) => {
return (str: unknown):str is Lowercase<Extract<T[keyof T], string>> => {
return Object.values(enumObj).map((i) => i.toLowerCase()).includes(str);
}
}
// 物件轉陣列
export const objectToArray = <T extends object>(object: T) => {
const res: T[keyof T][] = [];
const isObjKey = isKeyOfEnum(object);
Object.keys(object).forEach((key) => {
if (isObjKey(key)) {
res.push(object[key]);
}
});
return res;
};
參考資料
Extending Types
type guard function doesn't work. type still be judged as string