Skip to content

Commit ae10704

Browse files
committed
Describe known limitations
1 parent 741936e commit ae10704

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,44 @@ export const C = props => {
196196
- [ ] Transform the second parameter for the legacy `contextTypes`
197197
- [ ] Transform `static propTypes` to assignments
198198
- [x] Rename local variables in `render` if necessary
199+
200+
## Known limitations
201+
202+
### Class refs
203+
204+
Symptom: you get the following type error:
205+
206+
```
207+
test.tsx:1:1 - error TS2322: Type '{ ... }' is not assignable to type 'IntrinsicAttributes & Props'.
208+
Property 'ref' does not exist on type 'IntrinsicAttributes & Props'.
209+
210+
1 ref={ref}
211+
~~~
212+
```
213+
214+
Cause: class components receives refs, and the ref points to the instance of the class. Functional components do not receive refs by default.
215+
216+
Solution: this is not implemented now. However, once it is implemented you can opt in ref support by certain directives. It will generate `forwardRef` + `useImperativeHandle` to expose necessary APIs.
217+
218+
### Stricter render types
219+
220+
Symptom: you get the following type error:
221+
222+
```
223+
test.tsx:1:1 - error TS2322: Type '(props: Props) => ReactNode' is not assignable to type 'FC<Props>'.
224+
Type 'ReactNode' is not assignable to type 'ReactElement<any, any> | null'.
225+
226+
1 const C: React.FC<Props> = (props) => {
227+
~
228+
```
229+
230+
Cause: in DefinitelyTyped, `React.FC` is typed slightly stricter than the `render` method. You are expected a single element or `null`.
231+
232+
We leave this untransformed because it is known not to cause problems at runtime. An extra layer of a frament `<> ... </>` suffices to fix the type error.
233+
234+
## Assumptions
235+
236+
- It assumes that the component only needs to reference the latest values of `this.props` or `this.state`. This assumption is necessary because there is a difference between class components and funtion components in how the callbacks capture props or states. To transform the code in an idiomatic way, this assumption is necessary.
237+
- It assumes, by default, the component is always instantiated without refs.
238+
- It assumes that the methods always receive the same `this` value as the one when the method is referenced.
239+
- It assumes that the component does not update the state conditionally by supplying `undefined` to `this.setState`. We need to replace various functionalities associated with `this` with alternative tools and the transformation relies on the fact that the value of `this` is stable all across the class lifecycle.

0 commit comments

Comments
 (0)