Как вы аннотируете тип потока функции, которая возвращает часть состояния? - PullRequest
0 голосов
/ 10 октября 2018

Справочная информация:

В настоящее время мой метод registerOneTarget аннотирован так, что возвращает все LazyloadProviderState, и это неверно, поскольку он возвращает только часть полного состояния.Мой метод registerOneTarget получает цель и возвращает функцию , которая возвращает фрагмент состояния .

Вопрос:

Как выаннотировать один ключ большего типа (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,
};

Функция с указанным типом возврата:

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

Полный класс, если это поможет понять

 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>
    );
  }
}

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Лучше явно указать, какую часть состояния вы возвращаете - {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),
        },
      };
    };
  }
0 голосов
/ 11 октября 2018

Вы можете попробовать $ Shape :

Копирует форму поставляемого типа, но помечает каждое поле как необязательное.

Итак, ваша функцияаннотация будет выглядеть следующим образом:

LazyloadProviderState => $Shape<LazyloadProviderState>

Другое (и, я думаю, более простое) решение может заключаться в том, чтобы извлечь часть возвращенного состояния в отдельный тип:

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

И затем вы можете определить полноенаберите как содержит частичный тип:

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

, и тогда становится очень легко определить функцию:

LazyloadProviderState => LazyloadProviderPartialState;
...