typescript 如何定义有序迭代器类型?

问题描述 投票:0回答:2
interface TestIterator {
    0: boolean;
    1: any;
    2: "abc";
    length: 3;
    [Symbol.iterator]: typeof Array.prototype[Symbol.iterator];
}

// I want to build an iterator type that can be used for unpacking, which can still keep the correct type order after unpacking
const arr: TestIterator = [true, {}, "abc"]

// The following a1, a2, a3 cannot get the correct type
const [a1, a2, a3] = arr

我尝试查看生成器构造的类型,我惊讶地发现生成器构造的类型也无法保持类型的顺序

function *gen()
{
    yield "abc";
    yield true;
    yield 123;
}

const view_inference_type = gen(); // The generator gets the type: const view_inference_type: Generator<true | "abc" | 123, void, unknown>

const [g1, g2, g3] = view_inference_type; // All types of g1 g2 g3 are true | "abc" | 123 .This surprises me. Normally, we expect the unpackaged types to be sequential and accurate enough

我遇到的真正问题是,我正在使用接口的合并功能来扩展 Axios 的 AxiosResponse 接口,以便它可以解包,但我当前的方法没有获得正确的类型,因此元组方法偏离了问题。

declare module "axios"
{

    interface AxiosResponse {
        0: boolean;
        1: any;
        2: "async_try";
        length: 3;
        [Symbol.iterator]: Array[Symbol.iterator];

    }

}

有没有办法对迭代器或生成器的类型进行排序,或者手动指定类型的顺序?

typescript
2个回答
0
投票

对于您的场景,我认为正确的结构是元组。 查看官方文档。

type TestTuple = [boolean, any,string];

https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types


0
投票

在 TypeScript 中,迭代器和生成器当前不支持推断生成值的确切顺序(从 v5.4.5 开始)。可迭代的类型被推断为所有可能元素的类型的联合,而不管产生值的顺序如何。

但是,有一个解决方法可以解决此限制。即使实际值来自生成器,也可以从元组推断出值的类型。这是一个例子:

function test() {
  const a = 'a'
  const b = 'b'
  const c = 'c'

  // Define a payload with constant properties
  const accessiblePayload = { a, b, c } as const

  // Define a tuple for iterable values
  const iterablePayload = [a, b] as const

  return {
    ...accessiblePayload,
    ...iterablePayload,
    [Symbol.iterator]: function* () {
      for (const item of iterablePayload) {
        yield item
      }
    }
  }
}

// Destructure the returned object into foo and bar
const [foo, bar] = test()
console.log(foo, bar)  // Outputs: 'a', 'b'

// Destructure the returned object into a, b, and c
const { a, b, c } = test()
console.log(a, b, c)  // Outputs: 'a', 'b', 'c'

// Iterate over the returned object
for (const baz of test()) {
  console.log(baz)  // Outputs: 'a', 'b'
}

在此示例中,foo 和 bar 分别被推断为“a”和“b”,即使它们是由生成器函数生成的。这是因为它们的类型是从元组 iterablePayload 推断出来的,而不是从生成器函数本身推断出来的。

我希望这有帮助!如果您有任何疑问,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.