您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

functions.ts 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import _ from 'lodash';
  2. import { connect as reduxConnect } from 'react-redux';
  3. import { IReduxState } from '../../app/types';
  4. import { IStateful } from '../app/types';
  5. /**
  6. * Sets specific properties of a specific state to specific values and prevents
  7. * unnecessary state changes.
  8. *
  9. * @param {T} target - The state on which the specified properties are to
  10. * be set.
  11. * @param {T} source - The map of properties to values which are to be set
  12. * on the specified target.
  13. * @returns {T} The specified target if the values of the specified
  14. * properties equal the specified values; otherwise, a new state constructed
  15. * from the specified target by setting the specified properties to the
  16. * specified values.
  17. */
  18. export function assign<T extends Object>(target: T, source: Partial<T>): T {
  19. let t = target;
  20. for (const property in source) { // eslint-disable-line guard-for-in
  21. t = _set(t, property, source[property], t === target);
  22. }
  23. return t;
  24. }
  25. /**
  26. * Wrapper function for the react-redux connect function to avoid having to
  27. * declare function types for flow, but still let flow warn for other errors.
  28. *
  29. * @param {any} mapStateToProps - Redux mapStateToProps function.
  30. * @param {Function?} mapDispatchToProps - Redux mapDispatchToProps function.
  31. * @returns {Connector}
  32. */
  33. export function connect(
  34. mapStateToProps?: any, mapDispatchToProps?: Function | Object) {
  35. return reduxConnect(mapStateToProps, mapDispatchToProps);
  36. }
  37. /**
  38. * Determines whether {@code a} equals {@code b} according to deep comparison
  39. * (which makes sense for Redux and its state definition).
  40. *
  41. * @param {*} a - The value to compare to {@code b}.
  42. * @param {*} b - The value to compare to {@code a}.
  43. * @returns {boolean} True if {@code a} equals {@code b} (according to deep
  44. * comparison); false, otherwise.
  45. */
  46. export function equals(a: any, b: any) {
  47. return _.isEqual(a, b);
  48. }
  49. /**
  50. * Sets a specific property of a specific state to a specific value. Prevents
  51. * unnecessary state changes (when the specified {@code value} is equal to the
  52. * value of the specified {@code property} of the specified {@code state}).
  53. *
  54. * @param {T} state - The (Redux) state from which a new state is to be
  55. * constructed by setting the specified {@code property} to the specified
  56. * {@code value}.
  57. * @param {string} property - The property of {@code state} which is to be
  58. * assigned the specified {@code value} (in the new state).
  59. * @param {*} value - The value to assign to the specified {@code property}.
  60. * @returns {T} The specified {@code state} if the value of the specified
  61. * {@code property} equals the specified <tt>value/tt>; otherwise, a new state
  62. * constructed from the specified {@code state} by setting the specified
  63. * {@code property} to the specified {@code value}.
  64. */
  65. export function set<T extends Object>(state: T, property: keyof T, value: any): T {
  66. return _set(state, property, value, /* copyOnWrite */ true);
  67. }
  68. /* eslint-disable max-params */
  69. /**
  70. * Sets a specific property of a specific state to a specific value. Prevents
  71. * unnecessary state changes (when the specified {@code value} is equal to the
  72. * value of the specified {@code property} of the specified {@code state}).
  73. *
  74. * @param {T} state - The (Redux) state from which a state is to be
  75. * constructed by setting the specified {@code property} to the specified
  76. * {@code value}.
  77. * @param {string} property - The property of {@code state} which is to be
  78. * assigned the specified {@code value}.
  79. * @param {*} value - The value to assign to the specified {@code property}.
  80. * @param {boolean} copyOnWrite - If the specified {@code state} is to not be
  81. * modified, {@code true}; otherwise, {@code false}.
  82. * @returns {T} The specified {@code state} if the value of the specified
  83. * {@code property} equals the specified <tt>value/tt> or {@code copyOnWrite}
  84. * is truthy; otherwise, a new state constructed from the specified
  85. * {@code state} by setting the specified {@code property} to the specified
  86. * {@code value}.
  87. */
  88. function _set<T extends Object>(
  89. state: T,
  90. property: keyof T,
  91. value: any,
  92. copyOnWrite: boolean): T {
  93. // Delete state properties that are to be set to undefined. (It is a matter
  94. // of personal preference, mostly.)
  95. if (typeof value === 'undefined'
  96. && Object.prototype.hasOwnProperty.call(state, property)) {
  97. const newState = copyOnWrite ? { ...state } : state;
  98. if (delete newState[property]) {
  99. return newState;
  100. }
  101. }
  102. if (state[property] !== value) {
  103. if (copyOnWrite) {
  104. return {
  105. ...state,
  106. [property]: value
  107. };
  108. }
  109. state[property] = value;
  110. }
  111. return state;
  112. }
  113. /* eslint-enable max-params */
  114. /**
  115. * Returns redux state from the specified {@code stateful} which is presumed to
  116. * be related to the redux state (e.g. The redux store, the redux
  117. * {@code getState} function).
  118. *
  119. * @param {Function|IStore} stateful - The entity such as the redux store or the
  120. * redux {@code getState} function from which the redux state is to be
  121. * returned.
  122. * @returns {Object} The redux state.
  123. */
  124. export function toState(stateful: IStateful): IReduxState {
  125. if (stateful) {
  126. if (typeof stateful === 'function') {
  127. return stateful();
  128. }
  129. // @ts-ignore
  130. const { getState } = stateful;
  131. if (typeof getState === 'function') {
  132. return getState();
  133. }
  134. }
  135. // @ts-ignore
  136. return stateful;
  137. }