Skip to content

Commit

Permalink
fix: Switch was falling through to default if an element returned a f…
Browse files Browse the repository at this point in the history
…unction resolving to null
  • Loading branch information
jmeistrich committed Dec 1, 2023
1 parent 7e73970 commit ceb4ad9
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
13 changes: 6 additions & 7 deletions src/react/Switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,29 @@ export function Switch<T extends object>({
}: {
value?: Selector<T>;
children: Partial<Record<keyof T | 'null' | 'undefined' | 'default', () => ReactNode>>;
}): ReactElement;
}): ReactElement | null;
export function Switch<T extends string | number | symbol>({
value,
children,
}: {
value?: Selector<T>;
children: Partial<Record<T | 'null' | 'undefined' | 'default', () => ReactNode>>;
}): ReactElement;
}): ReactElement | null;
export function Switch<T extends boolean>({
value,
children,
}: {
value?: Selector<T>;
children: Partial<Record<'false' | 'true' | 'null' | 'undefined' | 'default', () => ReactNode>>;
}): ReactElement;
}): ReactElement | null;
export function Switch<T>({
value,
children,
}: {
value?: Selector<T>;
children: Partial<Record<any, () => ReactNode>>;
}): ReactElement {
}): ReactNode {
// Select from an object of cases
return ((children as Record<any, () => ReactNode>)[useSelector(value, { skipCheck: true })!]?.() ??
(children as Record<any, () => ReactNode>)['default']?.() ??
null) as ReactElement;
const child = children[useSelector(value, { skipCheck: true })!];
return (child ? child() : children['default']?.()) ?? null;
}
28 changes: 28 additions & 0 deletions tests/react.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useObserve } from '../src/react/useObserve';
import { useObserveEffect } from '../src/react/useObserveEffect';
import { useSelector } from '../src/react/useSelector';
import { useObservableState } from '../src/react/useObservableState';
import { Switch } from '../src/react/Switch';

type TestObject = { id: string; label: string };

Expand Down Expand Up @@ -527,6 +528,33 @@ describe('Show', () => {
});
});

describe('Switch', () => {
test('Switch does not fall through', async () => {
const obs = observable<{ ok: string }>({
ok: undefined as unknown as string,
});
let didFallThrough = false;
function Test() {
return createElement(
Switch,
// @ts-expect-error asdf
{ value: obs.ok },
{
undefined: () => {
return null;
},
default: () => {
didFallThrough = true;
return null;
},
},
);
}
render(createElement(Test));

expect(didFallThrough).toEqual(false);
});
});
describe('useObservableReducer', () => {
test('useObservableReducer test1', () => {
let nextId = 3;
Expand Down

0 comments on commit ceb4ad9

Please sign in to comment.