[英]How can I make a check on a string to narrow it down to the strings in an enum, and have TypeScript recognize it (node example)?
使用基本的node.js,在http.createServer
我接受了request
,並從請求中獲取了path
。 我有一個router
對象,以路徑為鍵,其值為處理程序函數。
// index.ts
export interface DataObject {
queryStringObject: ParsedUrlQuery;
method: string;
headers: IncomingHttpHeaders;
payload: any;
}
export type HandlerCallback = (statusCode: number, payload?: Object) => any;
export type Handler = (data: DataObject, callback: HandlerCallback) => any;
interface Router {
ping: Handler;
users: Handler;
adminUsers: Handler;
tokens: Handler;
}
// Define request router
const router: Router = {
ping: handlers.ping,
users: handlers.users,
adminUsers: handlers.adminUsers,
tokens: handlers.tokens,
};
export enum RestMethods {
get = 'get',
post = 'post',
put = 'put',
delete = 'delete',
}
export type RestHandler = {
[method in RestMethods]: Handler;
};
然后,我有了定義handlers
的文件:
interface Handlers {
users: Handler;
adminUsers: Handler;
tokens: Handler;
notFound: Handler;
ping: Handler;
}
interface SubHandlers {
users: RestHandler;
adminUsers: RestHandler;
tokens: RestHandler;
}
export const handlers: Handlers = {
users: (data, callback) => {
const acceptableMethods = ['get', 'post', 'put', 'delete'];
if (acceptableMethods.indexOf(data.method) !== -1) {
subHandlers.users[data.method](data, callback);
}
},
(...)
我在subhandlers.users[data.method]...
行上subhandlers.users[data.method]...
typescript
錯誤subhandlers.users[data.method]...
錯誤:(62、14)TS7053:元素隱式具有“任意”類型,因為類型“字符串”的表達式不能用於索引類型“路由器”。 在“路由器”類型上找不到帶有“字符串”類型參數的索引簽名。
data.method
是一個string
因為DataObject
以此方式定義它(傳入的請求可以在method
包含任何內容),並且subhandlers.users
是RestHandler
類型的,這是一個在枚舉RestMethods
具有鍵的對象。 但是我正在做檢查acceptableMethods.indexOf(data.method) !== -1
...我該如何進行檢查,以便Typescript可以意識到data.method僅限於枚舉中的字符串?
這里有兩個問題; 一種是推斷acceptableMethods
的類型為string[]
,而您希望編譯器跟蹤其包含的字符串文字值; 您可以使用const
斷言輕松地解決此問題,如下所示:
const acceptableMethods = ["get", "post", "put", "delete"] as const;
第二個問題是TypeScript無法理解或期望給定類型為T[]
的數組array
和值為val
,檢查array.indexOf(val) !== -1
應該將val
縮小為T
類型。 幸運的是,您可以通過創建用戶定義的類型防護函數來獲得此行為:
function arrayIncludes<T>(
arr: ReadonlyArray<T>,
val: any
): val is T {
return arr.indexOf(val) !== -1;
}
現在,您可以使用arrayIncludes()
代替indexOf
檢查,它應該可以為您工作:
export const handlers: Handlers = {
users: (data, callback) => {
const acceptableMethods = ["get", "post", "put", "delete"] as const;
if (arrayIncludes(acceptableMethods, data.method)) {
subHandlers.users[data.method](data, callback); // okay
}
}
};
有幫助嗎? 祝好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.