簡體   English   中英

如何檢查字符串以將其范圍縮小到枚舉中的字符串,並讓TypeScript識別它(節點示例)?

[英]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.usersRestHandler類型的,這是一個在枚舉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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM