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(
,