您如何注释 returns 状态片段的函数的流类型?

How do you annotate a flowtype of a function that returns a slice of state?

背景:

目前,我的 registerOneTarget 方法被注释为 return 整个 LazyloadProviderState,这是错误的,因为它只是 return 完整状态的一部分。我的 registerOneTarget 方法接受一个目标和 return 一个 函数,该函数 return 是状态的一部分

问题:

Inflow 如何注释较大类型的单个键(LazyloadProviderState)?换句话说,我们如何显式键入 LazyloadProviderState.targets 而不注释整个 LazyloadProviderState 类型?

州+类型:

export type LazyloadProviderState = {
  targets?: TargetHash,
  otherProps: any,
  id: number,
  meta: any,
};

export type Hash = string;

export type TargetHashMap = {
  [key: Hash]: Target,
};

export type Target = {
  key: Hash,
  current: Node,
  visibility: boolean,
};

函数 return 输入问题:

static registerOneTarget(
    target
  ) : (LazyloadProviderState => LazyloadProviderState) // wrong!
  {
    return ps => {
      return {
        targets: {
          ...ps.targets,
          ...LazyloadProvider.createElement(target),
        },
      };
    };
  }

完整class如果有助于理解

 class LazyloadProvider extends Component<
  LazyloadProviderProps,
  LazyloadProviderState
> {
  constructor(props) {
    super(props);
    this.state = {targets: {}};
  }

  static createHash(): Hash {
    let d, r;
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
      r = (new Date().getTime() + Math.random() * 16) % 16 | 0;
      d = Math.floor(d / 16);
      return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
    });
  }

  static createElement(target): TargetHash {
    const key = LazyloadProvider.createHash();
    const visibility = false;
    return {
      [key]: {
        ...target,
        key,
        visibility,
      },
    };
  }

  static registerOneTarget(
    target
  ): LazyloadProviderState => LazyloadProviderState {
    return ps => {
      return {
        targets: {
          ...ps.targets,
          ...LazyloadProvider.createElement(target),
        },
      };
    };
  }

  get engine() {
    return {
      state: this.state,
      register: target => {
        this.setState(LazyloadProvider.registerOneTarget(target));
      },
      deregister: target => {},
    };
  }

  render() {
    return (
      <LazyloadContext.Provider value={this.engine}>
        {this.props.children}
      </LazyloadContext.Provider>
    );
  }
}

你可以试试$Shape:

Copies the shape of the type supplied, but marks every field optional.

因此您的函数注释将是:

LazyloadProviderState => $Shape<LazyloadProviderState>

其他(我想更直接)解决方案可能是将返回的状态片段提取到单独的类型中:

export type LazyloadProviderPartialState = {
  targets?: TargetHash,
};

接下来您可以将完整类型定义为包含部分类型:

export type LazyloadProviderState = { 
  otherProps: any,
  id: number,
  meta: any,
} & LazyloadProviderPartialState;

然后定义函数就变得非常容易了:

LazyloadProviderState => LazyloadProviderPartialState;

最好明确说明要返回状态的哪一部分 - {targets: TargetHash}

export type LazyloadProviderState = {
  targets?: TargetHash,
  otherProps: any,
  id: number,
  meta: any,
};

static registerOneTarget(
    target
  ) : (LazyloadProviderState => {targets: TargetHash})
  {
    return ps => {
      return {
        targets: {
          ...ps.targets,
          ...LazyloadProvider.createElement(target),
        },
      };
    };
  }