typescript-vscode-plugins
typescript-vscode-plugins copied to clipboard
Code Actions for React
| - activation range
Create ref
Before:
<div ref={|} />
After:
const divRef = useRef<HTMLDivElement>()
<div ref={divRef} />
Also supports custom components that contain prop ref in types
Generate handler
Before:
<div onClick={|} />
After:
const handleDivClick = useCallback((event: MouseEvent<HTMLDivElement>) => {
}, []);
<div onClick={handleDivClick} />
Activated when the prop starts with on*, where * is any text starting with a capital letter. Also supports custom components that contain prop on* in types. Should automatically create an array of dependencies
Wrap handler into useCallback()
Before:
<div onClick={|(e) =>| { e.preventDefault() }} />
After:
const handleDivClick = useCallback((e: MouseEvent<HTMLDivElement>) => {
e.preventDefault();
}, []);
<div onClick={handleDivClick} />
Activation when an arrow function is passed as an argument to a prop. Should automatically create an array of dependencies.
Maybe we should improve the Wrap into useCallback instead of adding a new Code Action.
Create (prop_name) prop
Before:
// App.tsx
<MyComponent |newUnknownProp={123}| />
// MyComponent.tsx
interface Props {
someExistsProp: string;
}
const MyComponent: React.FC<Props> = (props) => ...
After:
// App.tsx
<MyComponent newUnknownProp={123} />
// MyComponent.tsx
interface Props {
someExistsProp: string;
newUnknownProp: number; // Infer type from value
}
const MyComponent: React.FC<Props> = (props) => ...
Activated when the user writes an unknown prop to a component. Should work only on components whose imports are outside of node_modules. If there is no Props interface, you need to create it. The type must be infered from the value, if there is no value, the boolean type by default.
Perhaps we need to create a setting that will control how to create types for the component:
- Via generics (
const MyComponent: React.FC<Props> = (props) => ...) - Via props (
const MyComponent = (props: Props) => ...) (should be default, reccomended by React)
This will also be useful for Create Props interface Code Action
Infer (useState|useRef) type
Before:
const [name, setName] = |useState|();
useEffect(() => {
setName('Agent_RBY_')
}, [])
After:
const [name, setName] = useState<string>();
useEffect(() => {
setName('Agent_RBY_')
}, [])
Activated when useState or useRef has no type specified.
For useState: if has a default value, then it must evaluate from it (except with null, undefined and [])
Create useState variable (variable_name)
Before:
<button name={|buttonName|} />
After:
const [buttonName, setButtonName] = useState<string>();
<button name={buttonName} />
Activated when an non-existing identifier is passed as a prop. The type must be infered from the prop type
Create ref
I suppose before example should contain not defined indentifier, so this is quickfix to define ref with the name (similar to Create (prop_name) prop or builtin define not defined method quickfix)
Generate handler
While Wrap handler into useCallback() will be easy to implement, this one will be much much harder I think. So the question is: why can't user write e => and then use Wrap handler into useCallback() callback? On the other hand, since this plugin is intended to work with vscode only, I guess we can find workaround here.
Wrap handler into useCallback()
I think this refactoring should should activate in following cases:
- any position in
=>of function or attribute name - either only attribute initializer selection (the whole function) or whole attribute selection
Create (prop_name) prop
I really like this one, but I was always in need for this in the following case:
interface Props {
someExistsProp: string;
}
const MyComponent: React.FC<Props> = (props) => {
props.newUnknownProp
}
Though if we use recommended way to specify Props interface TypeScript will suggest Declare missing property 'newUnknownProp' quickfix. So I'm good for adding this one.
Activated when useState or useRef has no type specified.
No type and initializer for useState. Also I think it would make sense to ignore setState invokations with callbacks.
And obviously declare property and add ref or useState won't have activation ranges since they are quickfixes