【问题标题】:How to type function params and make return type inferrable如何键入函数参数并使返回类型可推断
【发布时间】:2022-01-05 22:58:01
【问题描述】:

我想为始终接收相同类型参数的函数创建标准类型,但函数的 ReturnType 将取决于函数的可推断主体。

到目前为止,我有这两种方法可以部分完成工作:

我可以输入函数的参数,但不再推断响应。

type Handler = (req: NextApiRequest, res: NextApiResponse) => unknown
const getExamples: Handler = async (req, res) => {
  // req gets typed as 'NextApiRequest'
  return db.example.findMany()
}
// ReturnType gets typed as unknown
export type GetExamplesResponse = ReturnType<typeof getExamples>

我也可以推断出函数的 ReturnType,但参数现在隐含为 any。

const getExamples = async (req, res) => {
  // req is implicitly "any"
  return db.example.findMany()
}

// ReturnType gets typed as Promise<Example[]>
export type GetExamplesResponse = ReturnType<typeof getExamples>

有没有办法将这两种方法中最好的结合到一个通用类型/接口中,让我的 IDE 知道 req 和 res 的类型,同时允许 ReturnType 是可推断的?

Here's a typescript playground example without the imported types

【问题讨论】:

  • 简而言之,不可能。您需要将其包装在另一个函数调用中,但我想这是不可取的。
  • 我可以使用多个函数或类,只要它是可重用的,这是一个有效的解决方案
  • 请提供minimal reproducible example,清楚地表明您面临的问题。理想情况下,有人可以将代码粘贴到像 The TypeScript Playground (link here!) 这样的独立 IDE 中,然后立即着手解决问题,而无需首先重新创建它。不应有伪代码、拼写错误、不相关的错误或未声明的类型或值。
  • 你为什么不直接使用const getExamples = async (req: NextApiRequest, res: NextApiResponse) =&gt; {?然后推断返回类型。但是推断的返回类型不能检查(并且必须通过控制流分析来确定,这可能很慢),因此最好明确说明它们,特别是考虑到您显然想要使用那种类型。
  • @AlekseyL。您的两个 cmets 都可以被视为原始问题的答案,如果您将其发布为答案,我很乐意将其标记为正确的答案。

标签: typescript typescript-generics


【解决方案1】:

如果您明确指定函数类型const getExamples: Handler - 它将覆盖推断的类型。相反,您可以提供类型 其余参数:

type Params = [NextApiRequest, NextApiResponse]

const ex1 = async (...[req, res]: Params) => req.foo // Promise<string>
const ex2 = async (...[req, res]: Params) => res.bar // Promise<number>

Playground

其他选项是使用“工厂”功能:

const createHandler = <T>(handler: (req: NextApiRequest, res: NextApiResponse) => T) => handler;

// (req: NextApiRequest, res: NextApiResponse) => Promise<string>
const ex1 = createHandler(async (req, res) => {
    return req.foo
})

// (req: NextApiRequest, res: NextApiResponse) => Promise<number>
const ex2 = createHandler(async (req, res) => {
    return res.bar
})

Playground

【讨论】:

    猜你喜欢
    • 2022-12-04
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 2019-02-17
    相关资源
    最近更新 更多