Skip to content

Commit

Permalink
fix: isElementOfType Improved type inference (#2099)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bmingles authored Jun 25, 2024
1 parent 419ca39 commit e13c9d7
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
19 changes: 18 additions & 1 deletion packages/react-hooks/src/ElementUtils.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { createElement } from 'react';
import { Text } from '@adobe/react-spectrum';
import { ItemElement, Item, Text } from '@deephaven/components';
import { isElementOfType } from './ElementUtils';

beforeEach(() => {
jest.clearAllMocks();
expect.hasAssertions();
});

describe('isElementOfType', () => {
function MockComponent() {
return null;
Expand All @@ -21,4 +26,16 @@ describe('isElementOfType', () => {
expect(isElementOfType(element, type)).toBe(expected);
}
);

it('should derive the `type` prop', () => {
const element: ItemElement = createElement(Item);

if (isElementOfType(element, Item)) {
// This is a type check that verifies the type guard narrows this to the
// `Item` function instead of `string | JSXElementConstructor<any>`. This
// proves that #2094 is working as expected. Namely, the compiler will
// complain if it thinks `type` could be a string.
expect(element.type.name).toEqual(Item.name);
}
});
});
18 changes: 13 additions & 5 deletions packages/react-hooks/src/ElementUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { isValidElement, ReactElement, ReactNode } from 'react';
import {
isValidElement,
JSXElementConstructor,
ReactElement,
ReactNode,
} from 'react';
import { InferComponentProps } from '@deephaven/utils';

/**
Expand All @@ -7,10 +12,13 @@ import { InferComponentProps } from '@deephaven/utils';
* @param type The type to check against
* @returns True if the node is a React element of the specified type
*/
export function isElementOfType<T>(
node: ReactNode,
type: T
): node is ReactElement<InferComponentProps<T>> {
export function isElementOfType<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
T extends string | JSXElementConstructor<any> =
| string
// eslint-disable-next-line @typescript-eslint/no-explicit-any
| JSXElementConstructor<any>,
>(node: ReactNode, type: T): node is ReactElement<InferComponentProps<T>, T> {
return isValidElement(node) && node.type === type;
}

Expand Down

0 comments on commit e13c9d7

Please sign in to comment.