Skip to content

Commit e13c9d7

Browse files
authored
fix: isElementOfType Improved type inference (#2099)
I missed the 2nd generic argument when I first wrote this util which made the `type` property resolve to `string | React.JSXElementConstructor<any>` in certain cases instead of the actual type. This should fix that. resolves #2094
1 parent 419ca39 commit e13c9d7

2 files changed

Lines changed: 31 additions & 6 deletions

File tree

packages/react-hooks/src/ElementUtils.test.tsx

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { createElement } from 'react';
2-
import { Text } from '@adobe/react-spectrum';
2+
import { ItemElement, Item, Text } from '@deephaven/components';
33
import { isElementOfType } from './ElementUtils';
44

5+
beforeEach(() => {
6+
jest.clearAllMocks();
7+
expect.hasAssertions();
8+
});
9+
510
describe('isElementOfType', () => {
611
function MockComponent() {
712
return null;
@@ -21,4 +26,16 @@ describe('isElementOfType', () => {
2126
expect(isElementOfType(element, type)).toBe(expected);
2227
}
2328
);
29+
30+
it('should derive the `type` prop', () => {
31+
const element: ItemElement = createElement(Item);
32+
33+
if (isElementOfType(element, Item)) {
34+
// This is a type check that verifies the type guard narrows this to the
35+
// `Item` function instead of `string | JSXElementConstructor<any>`. This
36+
// proves that #2094 is working as expected. Namely, the compiler will
37+
// complain if it thinks `type` could be a string.
38+
expect(element.type.name).toEqual(Item.name);
39+
}
40+
});
2441
});

packages/react-hooks/src/ElementUtils.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
import { isValidElement, ReactElement, ReactNode } from 'react';
1+
import {
2+
isValidElement,
3+
JSXElementConstructor,
4+
ReactElement,
5+
ReactNode,
6+
} from 'react';
27
import { InferComponentProps } from '@deephaven/utils';
38

49
/**
@@ -7,10 +12,13 @@ import { InferComponentProps } from '@deephaven/utils';
712
* @param type The type to check against
813
* @returns True if the node is a React element of the specified type
914
*/
10-
export function isElementOfType<T>(
11-
node: ReactNode,
12-
type: T
13-
): node is ReactElement<InferComponentProps<T>> {
15+
export function isElementOfType<
16+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
17+
T extends string | JSXElementConstructor<any> =
18+
| string
19+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
20+
| JSXElementConstructor<any>,
21+
>(node: ReactNode, type: T): node is ReactElement<InferComponentProps<T>, T> {
1422
return isValidElement(node) && node.type === type;
1523
}
1624

0 commit comments

Comments
 (0)