簡體   English   中英

在 TypeScript 中鍵入此函數的正確方法是什么?

[英]What is the correct way to type this function in TypeScript?

編輯:

我正在玩打字,因為我想避免返回Primise<any[]> ,我想要實現的是根據作為參數傳遞的列表為返回列表中的每個位置獲取正確的打字。

編輯2:

我得到的錯誤已被@outoftouch 解決,但不幸的是,函數輸入返回是這樣的:

const enabledResources: ({
  firstData: 'Some data',
  secondData: 'Some other data'
} | {
  thirdData: 'Some data',
  fourthData: 'Some other data'
} | undefined)[]

相反,期望的結果是:

const enabledResources: [
  { firstData: 'Some data', secondData: 'Some other data' } | undefined,
  { thirdData: 'Some data', fourthData: 'Some other data' } | undefined
]

如您所見,每個列表位置(在本例中為位置 0 和 1)已經通過作為參數傳遞的資源列表推斷出它們的類型。


原始問題

我想要一個函數,它獲取一個Resource列表作為第一個參數,該列表具有一個名為getResource的字段,該字段是一個返回Promise<T>的函數。

該函數必須驗證用戶是否有權獲取該數據,如果是,則在作為參數傳遞的相同位置返回該數據,否則在該列表位置返回undefined

我想如何使用這個功能的一個例子是:

const enabledResources = await getPageResources([
  {
    scope: 'some scope', // in User scopes
    getResource: Promise.resolve({ firstData: 'Some data', secondData: 'Some other data' }),
  },
  {
    scope: 'some other scope', // Not in user scopes
    getResource: Promise.resolve({ thirdData: 'Some data', fourthData: 'Some other data' }),
  },
]);

// This should log { firstData: 'Some data', secondData: 'Some other data' }
console.log(enabledResources[0]) 

// This should log undefined
console.log(enabledResources[1]) 

我試圖通過編寫這個函數來達到這個結果,但我在輸入時出錯:

export type Resource = {
  scope: Scope
  getResource: () => Promise<unknown>
}

export type Role = {
  name: string
  scopes: Scope[]
}

export async function getPageResources<T extends readonly Resource[]>(
  wantedResources: T,
  context: GetServerSidePropsContext<ParsedUrlQuery, PreviewData>
// I get error in the next line that says Type '"getResource"' cannot be used to index type 'T[P]'
): Promise<{ -readonly [P in keyof T]: Awaited<ReturnType<T[P]['getResource']>> | undefined }> {
  const session = await getSession(context)
  const userRole = session?.role as Role | null

  const resourcesToWait = wantedResources.map((e) => {
    const isInUserScopes = userRole?.scopes.includes(e.scope)
    return isInUserScopes ? e.getResource() : undefined
  })

  const resources = await Promise.all(resourcesToWait)

  return resources;
}

我實際上不明白為什么會這樣,在我看來T[P]應該是作為參數傳遞的列表中的元素,我應該得到等待返回的類型(或未定義),在正確的列表位置鍵入。

我究竟做錯了什么?

您可能忘記了P可以是數組的任何鍵。 例如,如果P"indexOf" ,則T[P]將是一個函數,並且函數沒有getResponse方法。

您必須首先使用extends明確檢查T[P]是否是 Resource :

): Promise<{
  -readonly [P in keyof T]: T[P] extends Resource
   ? Awaited<ReturnType<T[P]['getResource']>> | undefined
   : T[P];
}> {

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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