typescript 从常量数组中获取flatMap后的字符串文字

xwbd5t1u  于 2023-03-31  发布在  TypeScript
关注(0)|答案(3)|浏览(166)

我把一个数组声明为const:

const cloudRegionItems = [
  {
    category: 'Google Cloud',
    regions: [
      { value: 'v2018-us-central1', label: 'us-central1' },
      { value: 'europe-west1', label: 'europe-west1' },
    ],
  },
  {
    category: 'Amazon Web Services',
    regions: [
      { value: 'us-east-1', label: 'us-east-1' },
      { value: 'us-west-2', label: 'us-west-2' },
    ],
  },
] as const;

然后我想把上面提到的数组的区域变平。我是这样做的:

const cloudRegionOptions = cloudRegionItems.flatMap((item) => item.regions);

但是我得到了一个错误,就像这里提到的:

Type 'readonly [{ readonly value: "v2018-us-central1"; readonly label: "us-central1"; }, { readonly value: "europe-west1"; readonly label: "europe-west1"; }] | readonly [{ readonly value: "us-east-1"; readonly label: "us-east-1"; }, { ...; }]' is not assignable to type '{ readonly value: "v2018-us-central1"; readonly label: "us-central1"; } | { readonly value: "europe-west1"; readonly label: "europe-west1"; } | readonly ({ readonly value: "v2018-us-central1"; readonly label: "us-central1"; } | { ...; })[]'.
  Type 'readonly [{ readonly value: "us-east-1"; readonly label: "us-east-1"; }, { readonly value: "us-west-2"; readonly label: "us-west-2"; }]' is not assignable to type '{ readonly value: "v2018-us-central1"; readonly label: "us-central1"; } | { readonly value: "europe-west1"; readonly label: "europe-west1"; } | readonly ({ readonly value: "v2018-us-central1"; readonly label: "us-central1"; } | { ...; })[]'.
    Type 'readonly [{ readonly value: "us-east-1"; readonly label: "us-east-1"; }, { readonly value: "us-west-2"; readonly label: "us-west-2"; }]' is not assignable to type 'readonly ({ readonly value: "v2018-us-central1"; readonly label: "us-central1"; } | { readonly value: "europe-west1"; readonly label: "europe-west1"; })[]'.
      Type '{ readonly value: "us-east-1"; readonly label: "us-east-1"; } | { readonly value: "us-west-2"; readonly label: "us-west-2"; }' is not assignable to type '{ readonly value: "v2018-us-central1"; readonly label: "us-central1"; } | { readonly value: "europe-west1"; readonly label: "europe-west1"; }'.
        Type '{ readonly value: "us-east-1"; readonly label: "us-east-1"; }' is not assignable to type '{ readonly value: "v2018-us-central1"; readonly label: "us-central1"; } | { readonly value: "europe-west1"; readonly label: "europe-west1"; }'.
          Type '{ readonly value: "us-east-1"; readonly label: "us-east-1"; }' is not assignable to type '{ readonly value: "europe-west1"; readonly label: "europe-west1"; }'.
            Types of property 'value' are incompatible.
              Type '"us-east-1"' is not assignable to type '"europe-west1"'.

这里是操场:TSPlayground链接

mkshixfv

mkshixfv1#

问题是,当你flatMapitem.regions时,结果类型是一个可变的数组类型。由于item.regions是一个只读元组类型,赋值被破坏,并发生错误。你可以通过先Map,然后扁平化(这与flatMap相同)轻松解决这个问题:

const cloudRegionOptions = cloudRegionItems.map((item) => item.regions).flat();

这是可行的,因为map的结果被推断为只读元组的数组,并且由于所有item.regions都是只读元组,因此赋值有效。在Map之后,您可以平整数组,从而产生所需的结果。
Playground

5fjcxozz

5fjcxozz2#

我不知道我在Typescript中做什么,但以下两个似乎都在操场上工作:

const cloudRegionOptions = cloudRegionItems.flatMap((item): Readonly<Array<any>> => item.regions);

以及

const cloudRegionOptions = cloudRegionItems.flatMap((item) => [...item.regions])
xhv8bpkk

xhv8bpkk3#

.map(...).flat()是解决这个问题的最好方法,但是flatMap(...)的另一个声明也可以推断出正确缩小的类型:

interface ReadonlyArray<T> {
    flatMap<U extends (unknown | ReadonlyArray<unknown>), This = undefined> (
        callback: (this: This, value: T, index: number, array: T[]) => U,
        thisArg?: This
    ): U extends ReadonlyArray<unknown> ? U : U[]
}

相关问题