Coder Social home page Coder Social logo

typescript-cheatsheets / react Goto Github PK

View Code? Open in Web Editor NEW
45.2K 45.2K 4.1K 2.98 MB

Cheatsheets for experienced React developers getting started with TypeScript

Home Page: https://react-typescript-cheatsheet.netlify.app

License: MIT License

JavaScript 93.90% CSS 5.79% Shell 0.31%
cheatsheet guide hacktoberfest hacktoberfest2022 react typescript

react's People

Contributors

akameco avatar allcontributors[bot] avatar artola avatar arvindcheenu avatar azizhk avatar dance2die avatar dantehemerson avatar dependabot[bot] avatar dhurlburtusa avatar elit-altum avatar eps1lon avatar ferdaber avatar filiptammergard avatar github-actions[bot] avatar gnbaron avatar hskwakr avatar jasanst avatar jpavon avatar jsjoeio avatar maafaishal avatar markpollmann avatar maurer2 avatar mjsarfatti avatar orta avatar rinatvaliullov avatar ryota-murakami avatar stephenkoo avatar swyxio avatar tpetrina avatar tsiq-swyx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react's Issues

Thank you!

Just wanted to say what a phenomenal resource this is, even for experienced TypeScript developers. Thank you!

Context - Provider & Consumer should be a pair

Context shows how to create a provider but doesn't provide a way to use the Consumer.

What do you think about providing a code snippet for the consumer as well?

I can do a PR for the code snippet that shows how to consume using Consumer

Edit jlqo76kxov

import * as React from "react";
import { render } from "react-dom";
import { Provider, Consumer, ProviderStore } from "./components/Provider.tsx";

const App = () => (
  <div style={styles}>
    <Provider>
      <Consumer>
        {(store: ProviderStore) => (
          <div>
            <span>Theme Color: </span>
            <p style={{ color: store.state.themeColor }}>
              {store.state.themeColor}
            </p>
          </div>
        )}
      </Consumer>
    </Provider>
  </div>
);

render(<App />, document.getElementById("root"));

[Basic] Function Component alternative

What cheatsheet is this about? (if applicable)

Basic cheatsheet

What's your issue or idea?

The function component can be reduced to

function App({ message: string }) {
  return <div>{message}</div>;
}

instead of

const App: React.FunctionComponent<{ message: string }> = function App({ message }) {
  return <div>{message}</div>;
}

which is quite big & is weird syntactically at least in vanilla JS

const App = function App({ message ) {
  return <div>{message}</div>;
}

Also, would love some examples in Function Components section of What's the difference? each bullet points :)

Examples would be much better on these 2 bullet points since it makes grasping easier -

  • If you need to use children property inside the function body, in the former case it has to be added explicitly. FunctionComponent already includes the correctly typed children property which then doesn't have to become part of your type.
  • Typing your function explicitly will also give you typechecking and autocomplete on its static properties, like displayName, propTypes, and defaultProps

[translation] Add a translation link

Hi:
Thanks the great repo. I like it very much and I translated it into Chinese so more Chinese developer can read it easier, here's the repo link, would you like to add the link somewhere so more people may see this great repo? And I'll update the translation due to your updating. 😆
Best regards.

Link to official CRA

There is an official release of create-react-app with TypeScript support that will be available very shortly.

How do you feel about updating the docs to reference create-react-app directly instead of the wmonk/jpavon forks when the new version lands?

Also for reference: facebook/create-react-app#5581

State annotation inside the constructor

##If you have to initial your state inside the constructor, is it also recommended to add second annotation outside the constructor? something like:

class MyComponent extend<IProps, IState> {
    state: IState
    constructor (props: IProps) {
        super(props)
        this.setState({ name: props.name})
    }
}

P.S. Thanks for your awesome guideline ❤️❤️❤️

Extract proptypes in Typescript (interfaces)

How can I extract the proptypes (the interface) of a component in Typescript? I Know I can access the component and get the props easily, but I want to get the types, so that I can easily generate a nice show-case for my lib components.

How to describe type of props for children

// item is of PageItem type

const controls = _.map(items, item => <FVDesignerItem key={item.id} item={item} />);
        return (
            <FvPageWrapper>
                <FvPositioningContainer disabled={disabled}>{controls}</FvPositioningContainer>
            </FvPageWrapper>
        );

...
// FvPositioningContainer .tsx

React.Children.map(children, (child, i) => {
            if (!child) return undefined;
            const { x, y, w, h } = child.props.item;  // item here is of PageItem , propagated automatically and validated by tsc
           ....
        });

FunctionComponent and ComponentClass are not compatible with LibraryManagedAttributes

Annotating functions and classes with FunctionComponent and ComponentClass breaks LibraryManagedAttributes due to the static defaultProps property on those interfaces being set to optional.

import { FunctionComponent, ComponentClass, Component } from 'react'

export interface Props {
  foo: string
  bar?: boolean
}

const TestFunction: FunctionComponent<Props> = props => <div />
TestFunction.defaultProps = {
  foo: '',
}

const TestClass: ComponentClass<Props> = class TestClass extends Component<Props> {
  static defaultProps = {
    foo: '',
  }

  render() {
    return <div />
  }
}

// type is never
type TestDefaultProps = typeof TestFunction extends { defaultProps: infer D } ? D : never
type TestClassDefaultProps = typeof TestClass extends { defaultProps: infer D } ? D : never

// type is Props because typeof Test does not extend { defaultProps } but rather { defaultProps? }
type TestManagedProps = JSX.LibraryManagedAttributes<typeof TestFunction, Props>
type TestClassManagedProps = JSX.LibraryManagedAttributes<typeof TestClass, Props>

This causes defaultProps to be completely ignored by JSX.LibraryManagedAttributes. We should probably remove it as a recommendation from the cheat sheet for now.

Generic Components

What cheatsheet is this about? (if applicable)

Advanced cheatsheet

What's your issue or idea?

We should probably have a short section on authoring generic components -- components that take generic prop interfaces (or even state interfaces).

How best to document the setup, dev, and build process?

if I write too much I end up writing a typescript textbook. I would really like to avoid that. but sometimes there are little shitty issues when setting up and building a react+ typescript app. should I just have a separate BUILDING.md?

typo in Section 2: Getting Started example

In Section 2: Getting Started > What's the difference?

const App: React.FunctionComponent<{ message: string }> = function App({ message }) {
  return <div{message}</div>;
}

Should probably be:

const App: React.FunctionComponent<{ message: string }> = function App({ message }) {
  return <div>{message}</div>;
}

[Basic] ESLint complains about missing return type in React.FunctionComponent

Please see the following:

const CoolComponent: React.FunctionComponent<{}> = () => (
  <Fragment>
    CoolComponent
  </Fragment>
);

export default CoolComponent;

ESLint says: warning: Missing return type on function

Were the following:

const CoolComponent: React.FunctionComponent<{}> = (): ReactElement => (
  <Fragment>
    CoolComponent
  </Fragment>
);

export default CoolComponent;

Fixes the warning.

What do you think? What is the better code?

Types vs Interfaces

Spectrum discussion here brought up the Types vs Interfaces discussion. as far as I can tell there is no real difference between them. I personally always use interfaces but i dont have a strong reason apart from I can extend them if i need to. Should we recommend one or the other? anyone have a source?

[Basic] Custom hooks recommendation idea

What cheatsheet is this about? (if applicable)

Basic cheatsheet

What's your issue or idea?

Our team uses custom hooks a lot. We are testing out the idea to return objects rather than arrays. You see, it makes sense for the generic hook functions to return arrays because it's almost always useful to grab both the state and the setState function. Also the react provided hooks don't really know what you're going to "call" or "name" the hook variables. However when you write a custom hook it's very useless to return an array because you're now requiring the caller to grab and name every variable that is returned (up until the last variable they plan on using). With an object return, you provide a bag of named variables (which makes much more sense for a custom hook). That way the caller of the hook can decide to grab JUST the variables they might be interested in, and are not forced to make unused variables if they just want the setter, for example.

How to assign types to components?

I'm writing a component for React Native that shrinks or grows an image, depending on whether the keyboard is showing or not. I've already written and used in in JS. My recent project uses TypeScript. So I thought I could easly port it over. Well it turns out, I get the error message:

Property 'keyboardDidShowListener' does not exist on type 'Logo'.

Here is the code for the component:

import styles, { imageSizes } from "./styles";
import React, { Component } from "react";
import { Animated, Keyboard, Platform, View, EmitterSubscription } from "react-native";

const ANIMATION_DURATION = 250;

interface Props {}
interface State {
  containerImageWidth: Animated.Value;
}

export default class Logo extends Component<Props, State> {
  state = { containerImageWidth: new Animated.Value(imageSizes.$largeContainerSize) };

  componentDidMount = () => {
    const name = Platform.OS === "ios" ? "Will" : "Did";
    this.keyboardDidShowListener = Keyboard.addListener(
      `keyboard${name}Show`,
      this.keyboardWillShow
    );
    this.keyboardDidHideListener = Keyboard.addListener(
      `keyboard${name}Hide`,
      this.keyboardWillHide
    );
  };

  componentWillUnmount = () => {
    this.keyboardDidShowListener.remove();
    this.keyboardDidHideListener.remove();
  };

  keyboardWillShow = () => {
    Animated.timing(this.state.containerImageWidth, {
      toValue: imageSizes.$smallContainerSize,
      duration: ANIMATION_DURATION
    }).start();
  };

  keyboardWillHide = () => {
    Animated.timing(this.state.containerImageWidth, {
      toValue: imageSizes.$largeContainerSize,
      duration: ANIMATION_DURATION
    }).start();
  };

  render() {
    const containerImageStyles = [
      styles.containerImage,
      { width: this.state.containerImageWidth, height: this.state.containerImageWidth }
    ];

    return (
      <View style={styles.container}>
        <Animated.View style={containerImageStyles}>
          <Animated.Image
            resizeMode="contain"
            style={containerImageStyles}
            source={require("../../assets/logos/logo.png")}
          />
        </Animated.View>
      </View>
    );
  }
}

The lines

...
this.keyboardDidShowListener = Keyboard.addListener
...
this.keyboardDidHideListener = Keyboard.addListener
...

Throw the aforementioned error.

I tried fixing it by declaring:

keyboardDidShowListener: EmitterSubscription;

below the state. But this throws the error:

Property 'keyboardDidShowListener' has no initializer and is not definitely assigned in the constructor.

How would you fix this?

Misleading assumption about IDE capabilities

The "enum" part of the advanced section mentions the following:

A simpler alternative to enum is just declaring a bunch of strings with union, but this doesn't get autocompletion or syntactic benefits:

This is quite possible with WebStorm. Given

type Foo = 'a' | 'b'
const foo: Foo = 

and hitting Ctrl + Space, you'll get a list of "a" and "b" which you can choose from. For longer strings, you'll also get suggestions as you start typing them (including the camelCase autocompletion, etc.)

The autocompletion capabilities should generally not be mentioned in the guide at all since it pretty much depends on what software you're using for development, or at least it should mention which IDE (like Webstorm) or text editor (like VSC) did the writer have in mind.

[Improvement/Addition] Extracting and composing types using $ElementProps

Just thought i'd note something that i do, that may be useful for others.
Since TS 2.8's conditional types, its possible to extract a type parameter from another type (although maybe it was possible before but i didn't know how to do it).
This is essentially a port of flow's react utility type "ElementProps".
It allows you to extend another component easily, which assists with typing HOCs, and props spread.

eg:

// ReactUtilityTypes.d.ts
declare type $ElementProps<T> = T extends React.ComponentType<infer Props>
  ? Props extends object ? Props : never
  : never;

Then say you have some components which spread props to its child (almost like defaultProps, mapProps, withProps HOCs)
https://github.com/acdlite/recompose/blob/master/docs/API.md#withprops

//Components.tsx

/*
Std box component.
Eg <Box  display="flex" justifyContent="center" color="palevioletred" />
*/
const Box = (props: React.CSSProperties) => <div style={props} />

const Card =  ({title, children, ...props}: {title: string} & $ElementProps<typeof Box>) =>
<Box {...props}>{title}: {children}</Box>

We could have just used React.CSSProperties in place of $ElementProps<...>, but thats not really what we're trying to express. What if the component was from a 3rd party library and you didn't know where the Props interface was?
Eg:

import Paper from '@material-ui/core/Paper';

const Card =  ({title, children, ...props}: {title: string} & $ElementProps<typeof Paper>) =>
<Paper {...props}>{title}: {children}</Box>

Not only that, you can use https://github.com/piotrwitek/utility-types to express even more:

import Paper from '@material-ui/core/Paper';
import {Omit} from 'utility-types'

// Same as above except cannot be styled
const Card =  ({title, children, ...props}: {title: string} & Omit<$ElementProps<typeof Paper>, "style" | "className" | "classes">) =>
<Paper {...props}>{title}: {children}</Box>

Sorry if this is not succinct, just wasn't sure which parts are worth going in the cheatsheet or if other people would find this valuable.

Happy to write something more cheatsheet worthy or presentable if needed!

awesome advice from Ferdaber

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:

  • A common pitfall is that these patterns are not supported:
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:

  • I recommend annotating the 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:

  • I strongly do not recommend annotating 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:

  • I would just add that inlining the event handler when you don't need to optimize is recommended for better type inference:
// 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!

HOC typing example seems to be no longer valid as of [email protected]+

image

[email protected]
@types/[email protected]

The code from the Advanced section

Type '{ prop: string; } & Readonly<{ children?: ReactNode; }> & Readonly<Pick<T, Exclude<keyof T, "prop">>>' is not assignable to type 'IntrinsicAttributes & T & { children?: ReactNode; }'.
  Type '{ prop: string; } & Readonly<{ children?: ReactNode; }> & Readonly<Pick<T, Exclude<keyof T, "prop">>>' is not assignable to type 'T'.ts(2322)
import React from 'react'

type WithThemeProps = {
  prop: string;
}

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type Optionalize<T extends K, K> = Omit<T, keyof K>;

export function withTheme<T extends WithThemeProps = WithThemeProps>(WrappedComponent: React.ComponentType<T>) {
  // Try to create a nice displayName for React Dev Tools.
  const displayName = WrappedComponent.displayName || WrappedComponent.name || "Component";

  // Creating the inner component. The calculated Props type here is the where the magic happens.
  return class ComponentWithTheme extends React.Component<Optionalize<T, WithThemeProps>> {
    public static displayName = `withPages(${displayName})`;

    public render() {
      // this.props comes afterwards so the can override the default ones.
      return <WrappedComponent prop="prop" {...this.props} />;
    }
  }
}

How to handle conditional rendering?

Consider the following example:

type Component1Props = { ... }
const Component1: React.SFC<Component1Props> = props => { ... }

type Component2Props = { ... }
const Component2: React.SFC<Component2Props> = props => { ... }

const Component3: React.SFC<???> = props => {
   // some prop from Component1Props
   if(props.prop1) {
      return <Component1 {...props} />
   }
   
   // some prop from Component2Props
   if(props.prop2) {
      return <Component2 {...props} />
   }
}

Ideally I want typechecker to handle two things:

  1. It's required to pass either prop1 or prop2, but not both of them
  2. If prop1 is passed then props are of type Component1Props and if prop2 is passed then props are of type Component2Props

P. S. I'm completely new to TypeScript and I'm not sure that it's even possible)

Add example of dynamic HTML tags

Trying to find the "right" @types/react in the advance cheatsheet to use for dynamic HTML tag props. I'm struggling to find the right way of writing this in TS:

import React from "react";

type Props = {
  is?:
    | "h1"
    | "h2"
    | "h3"
    | "h4"
    | "h5"
    | "h6";
  children: React.ReactNode;
};

const Text = ({ is: Element, children }: Props) => (
  <Element>{children}</Element>
);

Text.defaultProps = {
  is: "span"
};

This produces the TS error: JSX element type 'Element' does not have any construct or call signatures

Based on the advanced docs, I've tried writing the is? type as :

  • JSX.InstrinsicElements<"h1"|"h2">
  • React.ReactElement<"h1"|"h2">
  • React.ElementType<"h1"|"h2">

But this isn't working. Any help is much appreciated!

Prettier + TSLint + ESLint

I have been playing around with this idea for some time. Why? I miss some of the plugins and functionality of eslint in typescript (ay11, import, airbnb, unicorn with some other plugins and configs.)

Here's my gist with settings: https://gist.github.com/azdanov/7e74ed6ce41536b08277f4121a4f5218

And a working repo:
https://github.com/azdanov/tslint-eslint-crats

What is important:

Issues:

Omit attribute from a type convoluted

In the section Omit attribute from a type you suggest the following snippet:

// here is the magic - omitting an attribute
type Diff<T extends string, U extends string> = ({ [P in T]: P } &
  { [P in U]: never } & { [x: string]: never })[T];
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
// end of magic

This is only necessary in TypeScript versions prior to 2.8 since it includes Excludes which simplifies writing Omit as seen in previous parts of the cheat sheet:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

I'd like to change that - any objections against a PR?

[Basic] Add coc.vim to tools section

What cheatsheet is this about? (if applicable)

Basic cheatsheet

What's your issue or idea?

I would like to add https://github.com/neoclide/coc.nvim to the tools section for vim. It's insanely powerful and is on its way to replicating VSCode level of integration for Vim.

Will send a PR with this change if you're up for it.

[Long Term Plan] Move to docusaurus

thanks to many people's contributions the cheatsheet is starting to get long, and im starting to think about how to scale this thing. i think FB's docusaurus is a good way to maintain readable and searchable react+typescript docs, while still allowing us to edit markdown easily.

the other big wishlist item i have is to note down the specific version features of Typescript that have particular significance or application in React. There will be a lot coming down with 3.0 but its hard for me to keep track with what happened since 2.0. a series of sections on each TS version would be an interesting an idea and allows people to learn cumulatively or starting from whatever base of knowledge they have.

Please add a workaround for Redux demo in Prerequisite 4

🤔 What?

Redux demo in 4. (optional) Read Microsoft's TypeScript-React-Starter docs fails to work as README is out of date.

  1. Failure 1
    Creating a store section - fix in Pull Request.

  2. Failure 2
    Making a container section - Fix in Pull Request.

For the demo program in TypeScript-React-Starter Redux demo to work, either

  1. PR needs to be merged
  2. or need to update the demo manually according to the changes as mentioned above.

🚀 Suggestion

Please provide users a heads-up when proceeding to go over the prerequisite 4 (optional) Read Microsoft's TypeScript-React-Starter docs.

[Suggestion] Extracting props of a component

Not sure where to put it, but I have these helper types in my team's codebase to extract the props of a component:

// helper type for all known valid JSX element constructors (class and function based)
type ElementConstructor<P> =
  | ((props: P) => React.ReactElement<any> | null)
  | (new (props: P) => React.Component<P, any, any>

// gets the internal props of a component
// used like Props<typeof MyComponent>
// or Props<'button'> for intrinsic HTML attributes
type Props<C> = C extends ElementConstructor<infer P>
  ? P
  : C extends keyof JSX.IntrinsicElements
  ? JSX.InstrinsicElements[C]
  : {}

// goes one step further and resolves with propTypes and defaultProps properties
type ApparentProps<C> = C extends ElementConstructor<infer P> ? JSX.LibraryManagedAttributes<C, P> : Props<C>

As far as how we use them, there's a lot of places where I want to reuse some slices of props because of prop drilling, and I can either export the props type as part of the module or I use this (either way works), the advantage of using this is that a refactor of the source of truth component will propagate to all consuming components.

I also use them to strongly type custom event handlers if they're not written at the call sites themselves (i.e. inlined with the JSX attribute):

// my-inner-component.tsx
export function MyInnerComponent(props: { onSomeEvent(event: ComplexEventObj, moreArgs: ComplexArgs): SomeWeirdReturnType }) { /* ... */ }

// my-consuming-component.tsx
export function MyConsumingComponent() {
  // event and moreArgs are contextually typed along with the return value
  const theHandler: Props<typeof MyInnerComponent>['onSomeEvent'] = (event, moreArgs) => {}
  return <MyInnerComponent onSomeEvent={theHandler} />
}

Typing for Context API where Context defaultValue is `null`

Hi there

There are times where we want the defaultValue for React's Context API to be null.

I've found this solution.

TLDR:

import * as React from 'react';

interface AppContextInterface {
  name: string,
  author: string,
  url: string
}

const {Provider, Consumer} = React.createContext<AppContextInterface | null>(null);

Now we can pass null in as a default value as our React.createContext argument.

Generic Component with forwarded ref.

Hello everyone,

today I stumbled across the following problem:

I want to build a List Component that has a generic prop . From the outside you can pass a ref to the List, to access a scrollToItem(item: TItem). Since I want to use hooks, I need to use React.forwardRef, which does not allow to return a generic function.

This is my attempt of solving, but I feel like there could be something less verbose and repetitive.

type ListRef<ItemType> = {
  scrollToItem: (item: ItemType) => void;
};

type ListProps<ItemType> = {
  items: ItemType[];
};

const List = forwardRef(function List<ItemType>(props: ListProps<ItemType>) {
  useImperativeHandle<ListRef<ItemType>, ListRef<ItemType>>(ref, () => ({
    scrollToItem: (item: ItemType) => undefined
  }));

  return null;
}) as <ItemType>(
  p: ListProps<ItemType> & { ref: Ref<ListRef<ItemType>> }
) => ReactElement<any> | null;

let ref = useRef<ListRef<number>>(null);

<List items={[1, 2, 3]} ref={ref} />;

typescript 怎么在可选属性上定义默认值

我想在可选属性上设置默认值,但是又不想在render 里给value 设默认值

const { value =5} = this.props

我找了很多方法,Partial也不行,以下是我代码
image
image
错误如下
image

import * as React from "react";

class App extends React.Component {
  public render() {
    return <A test={"a"} />;
  }
}

type AProps = {
  value?: number;
  [propName: string]: any;
};

class A extends React.Component<AProps, any> {
  static defaultProps = {
    value: 5,
  };
  public render() {
    const { value } = this.props;

    return <B value={value} />;
  }
}

type BProps = {
  value: number;
};
class B extends React.Component<BProps, any> {
  public render() {
    const { value } = this.props;

    return <div>{value}</div>;
  }
}

Assigning a type to a string that you are using as a react constructor

Hard to figure out how to write this, so I'll just give an example:

Example:

type Props = {
  headerTag: 'h1' | 'h2' | 'h3';
}

const ParentComponent: React.FC<Props> = (props) => {
  const HeaderTag = props.headerTag;
  const text = "Please someone help me type this correctly.";

  return <HeaderTag>{text}</HeaderTag>;
}

Error:

Type '{ children: string; }' has no properties in common with type 'IntrinsicAttributes'.

It doesn't like me giving any children to <HeaderTag> even though I know <h1> etc. can obviously have string children.

I tried typing the HeaderTag variable but I didn't know what to type it as, because Typescript knows headerTag is just a string.

The solution I came up with isn't really what I want to do, since it uses React.createElement:

return React.createElement(props.headerTag, {}, text)

How should I be doing?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.