Skip to content

Commit 233c261

Browse files
Add generic option type
1 parent 4ece5e0 commit 233c261

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

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

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

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

134135
beforeEach(() => {
@@ -238,7 +239,7 @@ describe('<Typeahead>', () => {
238239
{ disabled: true, name: 'boo' },
239240
{ name: 'baz' },
240241
{ disabled: true, name: 'bro' },
241-
];
242+
] as TestOption[];
242243

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

415-
const children = (state) => {
416+
const children = (state: TypeaheadState<TestOption>) => {
416417
selected = state.selected;
417418
};
418419
const selected1 = states.slice(0, 1);
@@ -464,7 +465,7 @@ describe('<Typeahead>', () => {
464465
render(
465466
<Controlled selected={states.slice(0, 1)}>
466467
{(state) => {
467-
selected = state.selected;
468+
selected = state.selected as TestOption[];
468469
}}
469470
</Controlled>
470471
);
@@ -485,7 +486,7 @@ describe('<Typeahead>', () => {
485486

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

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

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

@@ -1011,7 +1014,7 @@ describe('<Typeahead>', () => {
10111014
<Default
10121015
renderMenuItemChildren={
10131016
// Render the capital instead of the state name.
1014-
(o) => o.capital
1017+
(o) => <span>{o.capital}</span>
10151018
}
10161019
/>
10171020
);
@@ -1121,15 +1124,16 @@ describe('<Typeahead>', () => {
11211124
});
11221125

11231126
it('adds the custom option when `allowNew` is set to `true`', async () => {
1124-
let selected: TestOption[] = [];
1127+
type TestOptionWithId = TestOption & {id: string};
1128+
let selected: TestOptionWithId[] = [];
11251129
const user = userEvent.setup();
11261130

11271131
render(
11281132
<AllowNew
11291133
emptyLabel={emptyLabel}
11301134
newSelectionPrefix={newSelectionPrefix}
11311135
onChange={(s) => {
1132-
selected = s;
1136+
selected = s as TestOptionWithId[];
11331137
}}
11341138
/>
11351139
);
@@ -1211,7 +1215,7 @@ describe('<Typeahead>', () => {
12111215

12121216
describe('<Typeahead> Public Methods', () => {
12131217
it('exposes the typeahead instance and public methods', () => {
1214-
const ref = createRef<Typeahead>();
1218+
const ref = createRef<Typeahead<TestOption>>();
12151219
render(<TestComponent ref={ref} />);
12161220

12171221
expect(typeof ref.current?.blur).toBe('function');
@@ -1223,7 +1227,7 @@ describe('<Typeahead> Public Methods', () => {
12231227
});
12241228

12251229
it('calls the public `focus` and `blur` methods', () => {
1226-
const ref = createRef<Typeahead>();
1230+
const ref = createRef<Typeahead<TestOption>>();
12271231
render(<TestComponent ref={ref} />);
12281232

12291233
const input = getInput();
@@ -1237,7 +1241,7 @@ describe('<Typeahead> Public Methods', () => {
12371241

12381242
it('calls the public `clear` method', async () => {
12391243
const user = userEvent.setup();
1240-
const ref = createRef<Typeahead>();
1244+
const ref = createRef<Typeahead<TestOption>>();
12411245
const { container } = render(
12421246
<TestComponent multiple ref={ref} defaultSelected={states.slice(0, 3)} />
12431247
);
@@ -1256,13 +1260,13 @@ describe('<Typeahead> Public Methods', () => {
12561260
});
12571261

12581262
it('calls the public `getInput` method', () => {
1259-
const ref = createRef<Typeahead>();
1263+
const ref = createRef<Typeahead<TestOption>>();
12601264
render(<TestComponent ref={ref} />);
12611265
expect(ref.current?.getInput()).toEqual(getInput());
12621266
});
12631267

12641268
it('calls the public `hideMenu` method', async () => {
1265-
const ref = createRef<Typeahead>();
1269+
const ref = createRef<Typeahead<TestOption>>();
12661270
render(<TestComponent ref={ref} />);
12671271

12681272
getInput().focus();
@@ -1274,7 +1278,7 @@ describe('<Typeahead> Public Methods', () => {
12741278
});
12751279

12761280
it('calls the public `toggleMenu` method', () => {
1277-
const ref = createRef<Typeahead>();
1281+
const ref = createRef<Typeahead<TestOption>>();
12781282
render(<TestComponent ref={ref} />);
12791283

12801284
expect(getMenu()).not.toBeInTheDocument();
@@ -1288,7 +1292,7 @@ describe('<Typeahead> Public Methods', () => {
12881292

12891293
it('clears the typeahead after a selection', async () => {
12901294
const user = userEvent.setup();
1291-
const ref = createRef<Typeahead>();
1295+
const ref = createRef<Typeahead<TestOption>>();
12921296
const onChange = jest.fn(() => {
12931297
ref.current?.clear();
12941298
});
@@ -1474,7 +1478,7 @@ describe('<Typeahead> `change` events', () => {
14741478
});
14751479

14761480
it('does not call either when `clear()` is called externally', () => {
1477-
const ref = createRef<Typeahead>();
1481+
const ref = createRef<Typeahead<TestOption>>();
14781482
const selected = states.slice(0, 1);
14791483
render(
14801484
<TestComponent
@@ -1497,8 +1501,8 @@ describe('<Typeahead> `change` events', () => {
14971501

14981502
describe('<Typeahead> input value behaviors', () => {
14991503
let defaultInputValue: string;
1500-
let defaultSelected: Option[];
1501-
let selected: Option[];
1504+
let defaultSelected: TestOption[];
1505+
let selected: TestOption[];
15021506

15031507
beforeEach(() => {
15041508
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)