Skip to content

Commit 40a7e26

Browse files
Add generic option type
1 parent f63b836 commit 40a7e26

File tree

4 files changed

+32
-28
lines changed

4 files changed

+32
-28
lines changed

src/components/Typeahead/Typeahead.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ CustomMenu.args = {
123123
renderMenu: (results, menuProps) => (
124124
<Menu {...menuProps}>
125125
{/* Use `slice` to avoid mutating the original array */}
126-
{(results as TestOption[])
126+
{results
127127
.slice()
128128
.reverse()
129129
.map((r, index) => (

src/components/Typeahead/Typeahead.test.tsx

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
} from '../../tests/helpers';
2525

2626
import states, {TestOption} from '../../tests/data';
27+
import {TypeaheadState} from "../../types";
2728

2829
const ID = 'rbt-id';
2930

@@ -116,7 +117,7 @@ describe('<Typeahead>', () => {
116117
});
117118

118119
it('truncates selections when using `defaultSelected`', () => {
119-
let selected: TestOption[] = states.slice(0, 4);
120+
let selected = states.slice(0, 4);
120121
render(
121122
<Default defaultSelected={selected}>
122123
{(state) => {
@@ -129,7 +130,7 @@ describe('<Typeahead>', () => {
129130
});
130131

131132
describe('behaviors when selections are passed in', () => {
132-
let selected: { name: string }[];
133+
let selected: TestOption[];
133134
let selectedText: string;
134135

135136
beforeEach(() => {
@@ -239,7 +240,7 @@ describe('<Typeahead>', () => {
239240
{ disabled: true, name: 'boo' },
240241
{ name: 'baz' },
241242
{ disabled: true, name: 'bro' },
242-
];
243+
] as TestOption[];
243244

244245
render(<Default options={options} />);
245246
getInput().focus();
@@ -413,7 +414,7 @@ describe('<Typeahead>', () => {
413414
it('acts as a controlled input in single-select mode', () => {
414415
let selected: TestOption[] = [];
415416

416-
const children = (state) => {
417+
const children = (state: TypeaheadState<TestOption>) => {
417418
selected = state.selected;
418419
};
419420
const selected1 = states.slice(0, 1);
@@ -465,7 +466,7 @@ describe('<Typeahead>', () => {
465466
render(
466467
<Controlled selected={states.slice(0, 1)}>
467468
{(state) => {
468-
selected = state.selected;
469+
selected = state.selected as TestOption[];
469470
}}
470471
</Controlled>
471472
);
@@ -486,7 +487,7 @@ describe('<Typeahead>', () => {
486487

487488
describe('`highlightOnlyResult` behavior', () => {
488489
let onChange: jest.Mock;
489-
let selected: Option[];
490+
let selected: TestOption[];
490491

491492
beforeEach(() => {
492493
onChange = jest.fn((s) => (selected = [s]));
@@ -543,16 +544,18 @@ describe('<Typeahead>', () => {
543544

544545
it('does not highlight or select a disabled result', async () => {
545546
const user = userEvent.setup();
547+
const options = [
548+
{ name: 'foo' },
549+
{ disabled: true, name: 'bar' },
550+
{ disabled: true, name: 'boo' },
551+
{ name: 'baz' },
552+
] as TestOption[]
553+
546554
render(
547555
<Default
548556
highlightOnlyResult
549557
onChange={onChange}
550-
options={[
551-
{ name: 'foo' },
552-
{ disabled: true, name: 'bar' },
553-
{ disabled: true, name: 'boo' },
554-
{ name: 'baz' },
555-
]}
558+
options={options}
556559
/>
557560
);
558561

@@ -1012,7 +1015,7 @@ describe('<Typeahead>', () => {
10121015
<Default
10131016
renderMenuItemChildren={
10141017
// Render the capital instead of the state name.
1015-
(o) => o.capital
1018+
(o) => <span>{o.capital}</span>
10161019
}
10171020
/>
10181021
);
@@ -1145,15 +1148,16 @@ describe('<Typeahead>', () => {
11451148
});
11461149

11471150
it('adds the custom option when `allowNew` is set to `true`', async () => {
1148-
let selected: TestOption[] = [];
1151+
type TestOptionWithId = TestOption & {id: string};
1152+
let selected: TestOptionWithId[] = [];
11491153
const user = userEvent.setup();
11501154

11511155
render(
11521156
<AllowNew
11531157
emptyLabel={emptyLabel}
11541158
newSelectionPrefix={newSelectionPrefix}
11551159
onChange={(s) => {
1156-
selected = s;
1160+
selected = s as TestOptionWithId[];
11571161
}}
11581162
/>
11591163
);
@@ -1235,7 +1239,7 @@ describe('<Typeahead>', () => {
12351239

12361240
describe('<Typeahead> Public Methods', () => {
12371241
it('exposes the typeahead instance and public methods', () => {
1238-
const ref = createRef<Typeahead>();
1242+
const ref = createRef<Typeahead<TestOption>>();
12391243
render(<TestComponent ref={ref} />);
12401244

12411245
expect(typeof ref.current?.blur).toBe('function');
@@ -1247,7 +1251,7 @@ describe('<Typeahead> Public Methods', () => {
12471251
});
12481252

12491253
it('calls the public `focus` and `blur` methods', () => {
1250-
const ref = createRef<Typeahead>();
1254+
const ref = createRef<Typeahead<TestOption>>();
12511255
render(<TestComponent ref={ref} />);
12521256

12531257
const input = getInput();
@@ -1261,7 +1265,7 @@ describe('<Typeahead> Public Methods', () => {
12611265

12621266
it('calls the public `clear` method', async () => {
12631267
const user = userEvent.setup();
1264-
const ref = createRef<Typeahead>();
1268+
const ref = createRef<Typeahead<TestOption>>();
12651269
const { container } = render(
12661270
<TestComponent multiple ref={ref} defaultSelected={states.slice(0, 3)} />
12671271
);
@@ -1280,13 +1284,13 @@ describe('<Typeahead> Public Methods', () => {
12801284
});
12811285

12821286
it('calls the public `getInput` method', () => {
1283-
const ref = createRef<Typeahead>();
1287+
const ref = createRef<Typeahead<TestOption>>();
12841288
render(<TestComponent ref={ref} />);
12851289
expect(ref.current?.getInput()).toEqual(getInput());
12861290
});
12871291

12881292
it('calls the public `hideMenu` method', async () => {
1289-
const ref = createRef<Typeahead>();
1293+
const ref = createRef<Typeahead<TestOption>>();
12901294
render(<TestComponent ref={ref} />);
12911295

12921296
getInput().focus();
@@ -1298,7 +1302,7 @@ describe('<Typeahead> Public Methods', () => {
12981302
});
12991303

13001304
it('calls the public `toggleMenu` method', () => {
1301-
const ref = createRef<Typeahead>();
1305+
const ref = createRef<Typeahead<TestOption>>();
13021306
render(<TestComponent ref={ref} />);
13031307

13041308
expect(getMenu()).not.toBeInTheDocument();
@@ -1312,7 +1316,7 @@ describe('<Typeahead> Public Methods', () => {
13121316

13131317
it('clears the typeahead after a selection', async () => {
13141318
const user = userEvent.setup();
1315-
const ref = createRef<Typeahead>();
1319+
const ref = createRef<Typeahead<TestOption>>();
13161320
const onChange = jest.fn(() => {
13171321
ref.current?.clear();
13181322
});
@@ -1498,7 +1502,7 @@ describe('<Typeahead> `change` events', () => {
14981502
});
14991503

15001504
it('does not call either when `clear()` is called externally', () => {
1501-
const ref = createRef<Typeahead>();
1505+
const ref = createRef<Typeahead<TestOption>>();
15021506
const selected = states.slice(0, 1);
15031507
render(
15041508
<TestComponent
@@ -1521,8 +1525,8 @@ describe('<Typeahead> `change` events', () => {
15211525

15221526
describe('<Typeahead> input value behaviors', () => {
15231527
let defaultInputValue: string;
1524-
let defaultSelected: Option[];
1525-
let selected: Option[];
1528+
let defaultSelected: TestOption[];
1529+
let selected: TestOption[];
15261530

15271531
beforeEach(() => {
15281532
defaultInputValue = 'This is a default value';

src/core/Context.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createContext, useContext } from 'react';
22

3-
import {noop, once} from '../utils';
3+
import { noop, once } from '../utils';
44
import { Id, OptionType, OptionHandler, SelectEvent } from '../types';
55

66
export interface TypeaheadContextType<Option extends OptionType> {

src/core/Typeahead.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ class Typeahead<Option extends OptionType> extends React.Component<Props<Option>
519519
// Add a unique id to the custom selection. Avoid doing this in `render` so
520520
// the id doesn't increment every time.
521521
if (!isString(selection) && selection.customOption) {
522-
// @ts-ignore selection is an object
522+
// @ts-ignore selection is an object, since `isString` returned `false`
523523
selection = { ...selection , id: uniqueId('new-id-') };
524524
}
525525

0 commit comments

Comments
 (0)