Hi! I'm one of the contributors/maintainers to the @react/types library in DT, and I just have some suggested changes to the docs to ensure that folks who start with TS in React has a smoother experience!
For the section on Function Components:
const MyConditionalComponent = ({ shouldRender = false }) => shouldRender ? <div /> : false const MyArrayComponent = () => Array(5).fill(<div />) const el = <MyConditionalComponent /> // throws an error const el2 = <MyArrayComponentt /> // throws an error
This is because due to limitations in the compiler, function components cannot return anything other than a JSX expression or null
, otherwise it complains with a cryptic error message saying that the other type is not assignable to Element
. Unfortunately just annotating the function type will not help so if you really need to return other exotic types that React supports, you'd need to perform a type assertion:
const MyArrayComponent = () => Array(5).fill(<div />) as any as JSX.Element
For the section on Class Components:
state
class property in addition to adding it as the 2nd generic type parameter in the base class, because it allows better type inference when accessing this.state
and also initializing the state. This is because they work in two different ways, the 2nd generic type parameter will allow this.setState()
to work correctly, because that method comes from the base class, but initializing state
inside the component overrides the base implementation so you have to make sure that you tell the compiler that you're not actually doing anything different.type MyState = {} class App extends React.Component<{}, MyState> { state: MyState = {} }
For the section on Typing DefaultProps:
defaultProps
into a Partial
of your Props
interface. This causes issues that are a bit complex to explain here with the type inference working with JSX.LibraryManagedAttributes
. Basically it causes the compiler to think that when creating a JSX expression with that component, that all of its props are optional. Don't do this! Instead this pattern is recommended:type Props = Required<typeof MyComponent.defaultProps> & { /* additional props here */ } export class MyComponent extends React.Component<Props> { static defaultProps = { foo: 'foo' } }
For the section on Forms and Events:
// instead of this: const myHandler = (event: React.MouseEvent<HTMLButtonElement>) => {} const el = <button onClick={myHandler} /> // do this: const el = <button onClick={event => {}} />
This tells the compiler that there is no ambiguity to when the handler is being used, and adding function types to the call site allows it to infer the event
parameter's types right away.
That's all for now. I can definitely make a PR if y'all agree to these changes!
jpavon, tpetrina, sindresorhus, marcantoinepelletier, radiosilence and 10 moresibasishmyipei1028
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4