March 18, 2025
TS 索引簽名問題
[筆記] TS 索引簽名問題
const routes = {
home: "/",
admin: "/admin",
users: "/users",
};
const goToRoute = (route: "/" | "/admin" | "/users") => {};
goToRoute(routes.admin); // 此行會報錯
主要是因為 router 有可能會被修改所以是不一定可以被型別保護的。
所以重點應該是 要如何確認 routes 是不變的
- 加入
as const讓整個物件確認是不可變的
const routes = {
home: "/",
admin: "/admin",
users: "/users",
} as const;
- 利用
Object.freeze()去凍結物件, 但多層嵌套 會有問題
const routes = Object.freeze({
home: "/",
admin: "/admin",
users: "/users",
deep: {
route: "/xxxxxxxxxxx", // 此項是可以被修改的
},
});
- 加入
Record<string, string>作為型別索引簽名使用
const routes: Record<string, string> = {
home: "/",
admin: "/admin",
users: "/users",
deep: {
route: "/xxxxxxxxxxx", // 此項是可以被修改的
},
};
-
獲取
routes的型別定義,keyof typeof routes獲取每一個key值最後得到
Route = '/' | '/admin' | '.users'
const routes = {
home: "/",
admin: "/admin",
users: "/users",
};
type RouterKeys = keyof typeof routes;
type Route = (typeof routes)[RouterKeys];
// Route = '/' | '/admin' | '/users'
const goToRoute = (route: "/" | "/admin" | "/users") => {};
goToRoute(routes.admin); // 此行會報錯