【问题标题】:Get type of array values passed to function获取传递给函数的数组值的类型
【发布时间】:2020-07-11 09:07:29
【问题描述】:

我有一个函数,我接受字符串文字数组,然后根据给定数组推断第二个参数的类型。作为最简单的例子,让我们将第二个参数设为数组值之一

type Foo = (arr: any[], bar: typeof arr[number]) => any

你可能猜到 bar 类型实际上是 any,因为它在类型声明中是 any[],即使我提供了类似

fooFunc([const1, const2], somethingElse)

Typescript 将允许它。我知道您至少现在不能使用 const 参数,但是有什么解决方法可以使这项工作有效吗?

简单地将 arr 类型更改为 string[] 将不起作用

    const Codes = {
  "NOT_FOUND": "404",
  "FORBIDDEN": "403",
  "OK": "200"
   } as const

type Foo = (arr: string[], bar: typeof arr[number]) => any
const fooFunc: Foo = (arr, bar) => null;
fooFunc([Codes.FORBIDDEN, Codes.NOT_FOUND], "random string") //"random string" is string so it's completely ok

将 arr 类型更改为 Codes[] 也不起作用,因为它会允许 Codes.OK 不在我们的数组中。

【问题讨论】:

  • "我接受字符串数组" 那么它是 string[] 而不是 any[]。在这种情况下,第二个参数只会是string。这就是你想要的吗?
  • 如果我将其设为 string[],它将接受任何字符串,而不仅仅是我在数组中提供的文字。
  • 但是您拥有的文字 字符串。你到底想做什么?
  • 我已经用一段代码更新了我的问题,它显示了为什么这不起作用。它将允许使用任何字符串,而不仅仅是字符串文字。而且我正在尝试执行从第一个参数中的文字推断第二个参数类型的函数。我在推断第二个参数的类型时使用了更复杂的逻辑,但问题是一样的。它不会使用 typeof arr[number] 从第一个数组中获取类型
  • 所以你想确保第二个参数在给定的数组中?

标签: typescript


【解决方案1】:

一些好的 ol' typescript hacking 将解决您的问题。

const Codes = {
    "NOT_FOUND": "404",
    "FORBIDDEN": "403",
    "OK": "200"
} as const;
type Foo = <T extends typeof Codes[keyof typeof Codes], K extends T>(arr: T[], bar: K) => any;
const fooFunc: Foo = (arr, bar) => null;
fooFunc([Codes.NOT_FOUND, Codes.FORBIDDEN], Codes.NOT_FOUND); // allowed
fooFunc([Codes.NOT_FOUND, Codes.FORBIDDEN], Codes.FORBIDDEN); // allowed
fooFunc([Codes.NOT_FOUND, Codes.FORBIDDEN], Codes.OK); // errors
fooFunc(["123"], "123"); // errors

看到它在行动here

【讨论】:

  • 非常感谢您的回答,请您解释一下这种奇怪的通用交互是如何工作的或提供有关它的链接。我知道泛型是如何工作的,并且理解你使用的泛型是做什么的(至少我是这么认为的),但我仍然不明白为什么这个能工作而另一个不能。
  • 默认情况下,typescript 会为T 选择最小的联合类型,这将只是一个由arr 的所有元素组成的联合类型。然后,泛型要求bar 的类型,即K,是T 的子集(本质上是extends 的意思),这实质上意味着bar 在`arr.
猜你喜欢
  • 2012-11-24
  • 2014-12-15
  • 1970-01-01
  • 1970-01-01
  • 2021-02-07
  • 2012-05-30
  • 1970-01-01
  • 2020-08-03
  • 2018-04-04
相关资源
最近更新 更多