diff --git a/packages/react-is/src/ReactIs.js b/packages/react-is/src/ReactIs.js index e94599474dc19..809f09105cae1 100644 --- a/packages/react-is/src/ReactIs.js +++ b/packages/react-is/src/ReactIs.js @@ -56,6 +56,31 @@ export function typeOf(object: any) { return undefined; } +export function elementType(type: any) { + switch (type) { + case REACT_ASYNC_MODE_TYPE: + case REACT_FRAGMENT_TYPE: + case REACT_PROFILER_TYPE: + case REACT_STRICT_MODE_TYPE: + return type; + } + const typeofType = typeof type; + switch (typeofType) { + case 'string': + case 'function': + return REACT_ELEMENT_TYPE; + case 'object': + const $$typeof = type && type.$$typeof; + switch ($$typeof) { + case REACT_CONTEXT_TYPE: + case REACT_FORWARD_REF_TYPE: + case REACT_PROVIDER_TYPE: + return $$typeof; + } + } + return undefined; +} + export const AsyncMode = REACT_ASYNC_MODE_TYPE; export const ContextConsumer = REACT_CONTEXT_TYPE; export const ContextProvider = REACT_PROVIDER_TYPE; diff --git a/packages/react-is/src/__tests__/ReactIs-test.js b/packages/react-is/src/__tests__/ReactIs-test.js index 04c7cec745d70..d27da5215c554 100644 --- a/packages/react-is/src/__tests__/ReactIs-test.js +++ b/packages/react-is/src/__tests__/ReactIs-test.js @@ -71,6 +71,9 @@ describe('ReactIs', () => { expect(ReactIs.typeOf()).toBe( ReactIs.AsyncMode, ); + expect(ReactIs.elementType(React.unstable_AsyncMode)).toBe( + ReactIs.AsyncMode, + ); expect(ReactIs.isAsyncMode()).toBe(true); expect(ReactIs.isAsyncMode({type: ReactIs.AsyncMode})).toBe(false); expect(ReactIs.isAsyncMode()).toBe(false); @@ -80,6 +83,7 @@ describe('ReactIs', () => { it('should identify context consumers', () => { const Context = React.createContext(false); expect(ReactIs.typeOf()).toBe(ReactIs.ContextConsumer); + expect(ReactIs.elementType(Context.Consumer)).toBe(ReactIs.ContextConsumer); expect(ReactIs.isContextConsumer()).toBe(true); expect(ReactIs.isContextConsumer()).toBe(false); expect(ReactIs.isContextConsumer(
)).toBe(false); @@ -88,6 +92,7 @@ describe('ReactIs', () => { it('should identify context providers', () => { const Context = React.createContext(false); expect(ReactIs.typeOf()).toBe(ReactIs.ContextProvider); + expect(ReactIs.elementType(Context.Provider)).toBe(ReactIs.ContextProvider); expect(ReactIs.isContextProvider()).toBe(true); expect(ReactIs.isContextProvider()).toBe(false); expect(ReactIs.isContextProvider(
)).toBe(false); @@ -95,6 +100,7 @@ describe('ReactIs', () => { it('should identify elements', () => { expect(ReactIs.typeOf(
)).toBe(ReactIs.Element); + expect(ReactIs.elementType('div')).toBe(ReactIs.Element); expect(ReactIs.isElement(
)).toBe(true); expect(ReactIs.isElement('div')).toBe(false); expect(ReactIs.isElement(true)).toBe(false); @@ -115,6 +121,9 @@ describe('ReactIs', () => { it('should identify ref forwarding component', () => { const RefForwardingComponent = React.forwardRef((props, ref) => null); expect(ReactIs.typeOf()).toBe(ReactIs.ForwardRef); + expect(ReactIs.elementType(RefForwardingComponent)).toBe( + ReactIs.ForwardRef, + ); expect(ReactIs.isForwardRef()).toBe(true); expect(ReactIs.isForwardRef({type: ReactIs.StrictMode})).toBe(false); expect(ReactIs.isForwardRef()).toBe(false); @@ -123,6 +132,7 @@ describe('ReactIs', () => { it('should identify fragments', () => { expect(ReactIs.typeOf()).toBe(ReactIs.Fragment); + expect(ReactIs.elementType(React.Fragment)).toBe(ReactIs.Fragment); expect(ReactIs.isFragment()).toBe(true); expect(ReactIs.isFragment({type: ReactIs.Fragment})).toBe(false); expect(ReactIs.isFragment('React.Fragment')).toBe(false); @@ -140,6 +150,7 @@ describe('ReactIs', () => { it('should identify strict mode', () => { expect(ReactIs.typeOf()).toBe(ReactIs.StrictMode); + expect(ReactIs.elementType(React.StrictMode)).toBe(ReactIs.StrictMode); expect(ReactIs.isStrictMode()).toBe(true); expect(ReactIs.isStrictMode({type: ReactIs.StrictMode})).toBe(false); expect(ReactIs.isStrictMode()).toBe(false); @@ -150,6 +161,7 @@ describe('ReactIs', () => { expect( ReactIs.typeOf(), ).toBe(ReactIs.Profiler); + expect(ReactIs.elementType(React.unstable_Profiler)).toBe(ReactIs.Profiler); expect( ReactIs.isProfiler( ,