Skip to content

Commit c51c922

Browse files
br1anchenCompuIves
authored andcommitted
Fix Preference component props typing (codesandbox#2861)
1 parent 2b10811 commit c51c922

File tree

1 file changed

+69
-115
lines changed
  • packages/common/src/components/Preference

1 file changed

+69
-115
lines changed
Lines changed: 69 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,87 @@
11
import React from 'react';
22
import Tooltip from '../../components/Tooltip';
33

4-
import PreferenceSwitch from './PreferenceSwitch';
5-
import PreferenceDropdown, { NameMapper } from './PreferenceDropdown';
6-
import PreferenceNumber from './PreferenceNumber';
7-
import PreferenceText from './PreferenceText';
8-
import PreferenceKeybinding from './PreferenceKeybinding';
4+
import PreferenceSwitch, { Props as SwitchProps } from './PreferenceSwitch';
5+
import PreferenceDropdown, {
6+
Props as DropdownProps,
7+
} from './PreferenceDropdown';
8+
import PreferenceNumber, { Props as NumberProps } from './PreferenceNumber';
9+
import PreferenceText, { Props as TextProps } from './PreferenceText';
10+
import PreferenceKeybinding, {
11+
Props as KeybindingProps,
12+
} from './PreferenceKeybinding';
913
import { Container } from './elements';
1014

11-
export type Props = {
15+
type PreferenceType =
16+
| 'boolean'
17+
| 'string'
18+
| 'dropdown'
19+
| 'keybinding'
20+
| 'number';
21+
22+
type PreferenceProps<TString extends PreferenceType> = {
23+
type: TString;
1224
title: string;
1325
style?: React.CSSProperties;
1426
className?: string;
1527
tooltip?: string;
16-
} & (
17-
| BooleanPreference
18-
| StringPreference
19-
| DropdownPreference
20-
| KeybindingPreference
21-
| NumberPreference);
22-
23-
type SetValueT<T> = (value: T) => void;
24-
25-
export type BooleanPreference = {
26-
type: 'boolean';
27-
value: boolean;
28-
defaultValue?: boolean;
29-
setValue: SetValueT<boolean>;
30-
};
31-
32-
export type StringPreference = {
33-
type: 'string';
34-
value: string;
35-
defaultValue?: string;
36-
setValue: SetValueT<string>;
37-
};
38-
39-
export type DropdownPreference = {
40-
type: 'dropdown';
41-
options: string[];
42-
value: string;
43-
defaultValue?: string;
44-
setValue: SetValueT<string>;
45-
mapName?: NameMapper;
4628
};
4729

48-
export type KeybindingPreference = {
49-
type: 'keybinding';
50-
value: string[][];
51-
defaultValue?: string[][];
52-
setValue: SetValueT<string[][]>;
53-
};
54-
55-
export type NumberPreference = {
56-
type: 'number';
57-
value: number;
58-
defaultValue?: number;
59-
setValue: SetValueT<number>;
60-
};
30+
export type BooleanPreference = PreferenceProps<'boolean'> & SwitchProps;
6131

62-
export default class Preference extends React.Component<Props> {
63-
getOptionComponent = () => {
64-
const { props } = this;
65-
if (props.type === 'boolean') {
66-
return (
67-
<PreferenceSwitch
68-
{...props}
69-
setValue={props.setValue}
70-
value={props.value}
71-
/>
72-
);
73-
}
32+
export type StringPreference = PreferenceProps<'string'> & TextProps;
7433

75-
if (props.type === 'string') {
76-
return (
77-
<PreferenceText
78-
{...props}
79-
setValue={props.setValue}
80-
value={props.value}
81-
/>
82-
);
83-
}
34+
export type DropdownPreference = PreferenceProps<'dropdown'> & DropdownProps;
8435

85-
if (props.type === 'dropdown') {
86-
return (
87-
<PreferenceDropdown
88-
{...props}
89-
options={props.options}
90-
setValue={props.setValue}
91-
value={props.value}
92-
/>
93-
);
94-
}
36+
export type KeybindingPreference = PreferenceProps<'keybinding'> &
37+
KeybindingProps;
9538

96-
if (props.type === 'keybinding') {
97-
return (
98-
<PreferenceKeybinding
99-
{...props}
100-
setValue={props.setValue}
101-
value={props.value}
102-
/>
103-
);
104-
}
39+
export type NumberPreference = PreferenceProps<'number'> & NumberProps;
10540

106-
return (
107-
<PreferenceNumber
108-
{...props}
109-
setValue={props.setValue}
110-
value={props.value}
111-
/>
112-
);
113-
};
114-
115-
render() {
116-
const { title, style, className, tooltip } = this.props;
41+
export type Props =
42+
| BooleanPreference
43+
| StringPreference
44+
| DropdownPreference
45+
| KeybindingPreference
46+
| NumberPreference;
47+
48+
const Preference = (props: Props) => {
49+
const { title, style, className, tooltip, ...contentProps } = props;
50+
51+
let content: React.ReactNode;
52+
switch (
53+
contentProps.type // need 'type' as discriminant of union type
54+
) {
55+
case 'boolean':
56+
content = <PreferenceSwitch {...contentProps} />;
57+
break;
58+
case 'string':
59+
content = <PreferenceText {...contentProps} />;
60+
break;
61+
case 'dropdown':
62+
content = <PreferenceDropdown {...contentProps} />;
63+
break;
64+
case 'keybinding':
65+
content = <PreferenceKeybinding {...contentProps} />;
66+
break;
67+
default:
68+
content = <PreferenceNumber {...contentProps} />;
69+
}
11770

118-
const Title = tooltip ? (
119-
<Tooltip placement="right" content={tooltip}>
120-
{title}
121-
</Tooltip>
122-
) : (
123-
<span>{title}</span>
124-
);
71+
const Title = tooltip ? (
72+
<Tooltip placement="right" content={tooltip}>
73+
{title}
74+
</Tooltip>
75+
) : (
76+
<span>{title}</span>
77+
);
78+
79+
return (
80+
<Container style={style} className={className}>
81+
{Title}
82+
<div>{content}</div>
83+
</Container>
84+
);
85+
};
12586

126-
return (
127-
<Container style={style} className={className}>
128-
{Title}
129-
<div>{this.getOptionComponent()}</div>
130-
</Container>
131-
);
132-
}
133-
}
87+
export default Preference;

0 commit comments

Comments
 (0)