|
| 1 | +import type { ElementType, MemoExoticComponent, ReactElement } from 'react' |
| 2 | + |
| 3 | +// Directly ported from: |
| 4 | +// https://unpkg.com/browse/[email protected]/cjs/react-is.production.js |
| 5 | +// It's very possible this could change in the future, but given that |
| 6 | +// we only use these in `connect`, this is a low priority. |
| 7 | + |
| 8 | +const REACT_ELEMENT_TYPE = Symbol.for('react.element') |
| 9 | +const REACT_PORTAL_TYPE = Symbol.for('react.portal') |
| 10 | +const REACT_FRAGMENT_TYPE = Symbol.for('react.fragment') |
| 11 | +const REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode') |
| 12 | +const REACT_PROFILER_TYPE = Symbol.for('react.profiler') |
| 13 | +const REACT_PROVIDER_TYPE = Symbol.for('react.provider') |
| 14 | +const REACT_CONTEXT_TYPE = Symbol.for('react.context') |
| 15 | +const REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context') |
| 16 | +const REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref') |
| 17 | +const REACT_SUSPENSE_TYPE = Symbol.for('react.suspense') |
| 18 | +const REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list') |
| 19 | +const REACT_MEMO_TYPE = Symbol.for('react.memo') |
| 20 | +const REACT_LAZY_TYPE = Symbol.for('react.lazy') |
| 21 | +const REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen') |
| 22 | +const REACT_CLIENT_REFERENCE = Symbol.for('react.client.reference') |
| 23 | + |
| 24 | +export const ForwardRef = REACT_FORWARD_REF_TYPE |
| 25 | +export const Memo = REACT_MEMO_TYPE |
| 26 | + |
| 27 | +export function isValidElementType(type: any): type is ElementType { |
| 28 | + if (typeof type === 'string' || typeof type === 'function') { |
| 29 | + return true |
| 30 | + } // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill). |
| 31 | + |
| 32 | + if ( |
| 33 | + type === REACT_FRAGMENT_TYPE || |
| 34 | + type === REACT_PROFILER_TYPE || |
| 35 | + type === REACT_STRICT_MODE_TYPE || |
| 36 | + type === REACT_SUSPENSE_TYPE || |
| 37 | + type === REACT_SUSPENSE_LIST_TYPE || |
| 38 | + type === REACT_OFFSCREEN_TYPE |
| 39 | + ) { |
| 40 | + return true |
| 41 | + } |
| 42 | + |
| 43 | + if (typeof type === 'object' && type !== null) { |
| 44 | + if ( |
| 45 | + type.$$typeof === REACT_LAZY_TYPE || |
| 46 | + type.$$typeof === REACT_MEMO_TYPE || |
| 47 | + type.$$typeof === REACT_PROVIDER_TYPE || |
| 48 | + type.$$typeof === REACT_CONTEXT_TYPE || |
| 49 | + type.$$typeof === REACT_FORWARD_REF_TYPE || // This needs to include all possible module reference object |
| 50 | + // types supported by any Flight configuration anywhere since |
| 51 | + // we don't know which Flight build this will end up being used |
| 52 | + // with. |
| 53 | + type.$$typeof === REACT_CLIENT_REFERENCE || |
| 54 | + type.getModuleId !== undefined |
| 55 | + ) { |
| 56 | + return true |
| 57 | + } |
| 58 | + } |
| 59 | + |
| 60 | + return false |
| 61 | +} |
| 62 | + |
| 63 | +function typeOf(object: any): symbol | undefined { |
| 64 | + if (typeof object === 'object' && object !== null) { |
| 65 | + const $$typeof = object.$$typeof |
| 66 | + |
| 67 | + switch ($$typeof) { |
| 68 | + case REACT_ELEMENT_TYPE: { |
| 69 | + const type = object.type |
| 70 | + |
| 71 | + switch (type) { |
| 72 | + case REACT_FRAGMENT_TYPE: |
| 73 | + case REACT_PROFILER_TYPE: |
| 74 | + case REACT_STRICT_MODE_TYPE: |
| 75 | + case REACT_SUSPENSE_TYPE: |
| 76 | + case REACT_SUSPENSE_LIST_TYPE: |
| 77 | + return type |
| 78 | + |
| 79 | + default: { |
| 80 | + const $$typeofType = type && type.$$typeof |
| 81 | + |
| 82 | + switch ($$typeofType) { |
| 83 | + case REACT_SERVER_CONTEXT_TYPE: |
| 84 | + case REACT_CONTEXT_TYPE: |
| 85 | + case REACT_FORWARD_REF_TYPE: |
| 86 | + case REACT_LAZY_TYPE: |
| 87 | + case REACT_MEMO_TYPE: |
| 88 | + case REACT_PROVIDER_TYPE: |
| 89 | + return $$typeofType |
| 90 | + |
| 91 | + default: |
| 92 | + return $$typeof |
| 93 | + } |
| 94 | + } |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + case REACT_PORTAL_TYPE: { |
| 99 | + return $$typeof |
| 100 | + } |
| 101 | + } |
| 102 | + } |
| 103 | + |
| 104 | + return undefined |
| 105 | +} |
| 106 | + |
| 107 | +export function isContextConsumer(object: any): object is ReactElement { |
| 108 | + return typeOf(object) === REACT_CONTEXT_TYPE |
| 109 | +} |
| 110 | + |
| 111 | +export function isMemo(object: any): object is MemoExoticComponent<any> { |
| 112 | + return typeOf(object) === REACT_MEMO_TYPE |
| 113 | +} |
0 commit comments