You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为支持数组解构的AsyncStore定义正确TypeScript类型?

TypeScript类型定义:修复异步存储的解构类型问题

问题背景

需要为以下简化的JS函数定义TypeScript类型:

function asyncStore(initialValue) {
   return {
      ...createStore(initialValue),
      get 0() {
        return this
      },
      1: createStore('pending'),
      [Symbol.iterator]: function *() {
        yield this[0]
        yield this[1]
      }
   }
}

function createSomeEnhancedStore(sourceStore) {
  return {
    ...sourceStore,
    someEnhanceMethod() { /* ... */ }
  }
}

const [value, status] = createSomeEnhancedStore(asyncStore(0))

现有类型草稿如下:

/* Some deps */
interface Store<T> {
  value: T
}

type AnyStore = Store<any>

function createStore<T>(initialValue: T): Store<T> {
  return { value: initialValue }
}

/* Types for function */
interface AsyncStore<T> extends Store<T> {
  0: this,
  1: Store<'pending' | 'fulfilled' | 'rejected'>
}

function asyncStore<T>(initialValue: T): AsyncStore<T> {
   return {
      ...createStore(initialValue),
      get 0() {
        return this
      },
      1: createStore('pending'),
      [Symbol.iterator]: function *() {
        yield this[0]
        yield this[1]
      }
   }
}

function createSomeEnhancedStore<T extends AnyStore>(sourceStore: T): T & { someEnhanceMethod(): void } {
  return {
    ...sourceStore,
    someEnhanceMethod() { /* ... */ }
  }
}

const [value, status] = createSomeEnhancedStore(asyncStore(0))

当前遇到的问题:

  • 调用增强方法时类型校验正常:
    const enhancedStore = createSomeEnhancedStore(asyncStore(0))
    
    enhancedStore.someEnhanceMethod() // types ok
    enhancedStore[0].someEnhanceMethod() // types ok
    
  • 但数组解构时出现类型错误,尝试给AsyncStore添加迭代器类型后,解构得到的value和status类型变成了联合类型this | Store<'pending' | 'fulfilled' | 'rejected'>,不符合预期(预期value为this类型,status为Store<'pending' | 'fulfilled' | 'rejected'>类型)。

问题分析

原来的迭代器类型Iterator<this | Store<...>>会让TS认为每次yield的值是联合类型,无法区分顺序。要让解构时能推断出固定顺序的具体类型,需要让迭代器返回固定长度的元组类型,明确第一个值是this,第二个是状态存储类型。

解决方案

修改AsyncStore接口的Symbol.iterator定义,指定其返回的迭代器会产出一个包含两个元素的元组,这样TS就能准确推断解构后每个变量的类型:

interface AsyncStore<T> extends Store<T> {
  0: this;
  1: Store<'pending' | 'fulfilled' | 'rejected'>;
  [Symbol.iterator]: () => IterableIterator<[this, Store<'pending' | 'fulfilled' | 'rejected'>]>;
}

完整修正代码

/* Some deps */
interface Store<T> {
  value: T;
}

type AnyStore = Store<any>;

function createStore<T>(initialValue: T): Store<T> {
  return { value: initialValue };
}

/* Types for function */
interface AsyncStore<T> extends Store<T> {
  0: this;
  1: Store<'pending' | 'fulfilled' | 'rejected'>;
  [Symbol.iterator]: () => IterableIterator<[this, Store<'pending' | 'fulfilled' | 'rejected'>]>;
}

function asyncStore<T>(initialValue: T): AsyncStore<T> {
  return {
    ...createStore(initialValue),
    get 0() {
      return this;
    },
    1: createStore('pending'),
    [Symbol.iterator]: function* () {
      yield this[0];
      yield this[1];
    },
  };
}

function createSomeEnhancedStore<T extends AnyStore>(sourceStore: T): T & { someEnhanceMethod(): void } {
  return {
    ...sourceStore,
    someEnhanceMethod() { /* ... */ },
  };
}

// 现在解构类型正确:value为AsyncStore<number>,status为Store<'pending' | 'fulfilled' | 'rejected'>
const [value, status] = createSomeEnhancedStore(asyncStore(0));

验证效果

  • 解构后value的类型为AsyncStore<number> & { someEnhanceMethod(): void },可以正常调用someEnhanceMethod();
  • status的类型为Store<'pending' | 'fulfilled' | 'rejected'>,符合预期;
  • 原有的增强方法调用仍然保持类型正确。

内容的提问来源于stack exchange,提问作者dangreen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 13:14:52