Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Basic] Improve the class component defaultProps example #103

Merged

Conversation

VanTanev
Copy link
Contributor

@VanTanev VanTanev commented Apr 6, 2019

What cheatsheet is this about? (if applicable)

Basic cheatsheet

--

In the current example, we have a type definition for Props but do not make use of it for defaultProps. This can lead to a mismatch between the actual fields in defaultProps and what the Props type defines.

Adding an explicit Partial<Props> type to defaultProps seems like good example code.

In the current example, we have a type definition for props but do not
make use of it for defaultProps. This can lead to a mismatch between
defaultProps and props.
@VanTanev VanTanev changed the title Improve the class component defaultProps example [Basic] Improve the class component defaultProps example Apr 6, 2019
@swyxio
Copy link
Collaborator

swyxio commented Apr 8, 2019

good eye! thanks very much!

@swyxio swyxio merged commit 623a1d0 into typescript-cheatsheets:master Apr 8, 2019
@VanTanev
Copy link
Contributor Author

VanTanev commented Apr 8, 2019

@sw-yx Actually, I just checked, and the caveat that is stated under "Typescript 2.9 and earlier" still applies - defaultProps should not be typed as Partial<Props>, because that causes all component props to be considered optional in JSX (tested with typescript: 3.4.1 and @types/react: 16.8.12).

Another approach would be to use:

static defaultProps: Pick<Props, 'name'> = { name: 'world' }`

What do you think?

@ferdaber
Copy link
Collaborator

ferdaber commented Apr 9, 2019

A good way of working with defaultProps is to actually reverse the props definition so that it uses the defaultProps type and adds additional types:

type Props = typeof MyComponent.defaultProps & {
  age: number
}

class MyComponent extends Component<Props> {
  static defaultProps = {
    name: 'world'
  }
}

@swyxio
Copy link
Collaborator

swyxio commented Apr 9, 2019

o shit lets do that instead! much nicer.

swyxio added a commit that referenced this pull request Apr 9, 2019
@VanTanev
Copy link
Contributor Author

VanTanev commented Apr 9, 2019

I ran into a case where the typeof MyComponent.defaultProps pattern did not provide good ergonomics:

// in a separate file
interface ModelValues = {
  title: string
  description?: string
}

// in a custom formik form
type Props = {
  onSubmit: (values: ModelValues, actions: FormikActions<ModelValues>) => void
  initialValues: ModelValues
}

class ModelForm extends React.Component<Props> {
  static defaultProps: Pick<Props, 'initialValues'> = {
    initialValues: {
      title: ''
      description: ''
    }
  }
  render() { ...}
}

The reason I want to have a type definition directly on static defaultProps is that it protects me from omitting some value from the defaults, especially when dealing with more complicated props. Also, when there are type errors, they will directly show up in this file, instead of in the call sites.

@RiaanWest
Copy link

This has been merged, so not sure if y'all will see this, but:

This seems to now be possible if you make use of an interface for props:

export type IconSize = 'small' | 'regular' | 'medium' | 'large';

interface IconPropsInterface {
  icon: string;
  size?: IconSize;
}

export class Icon extends Component<IconPropsInterface> {
  static defaultProps: IconPropsInterface = {
    icon: '',
    size: 'regularrr',   <-- Throws: Type '"regularrr"' is not assignable to type '"small" | "regular" | "medium" | "large" | undefined'.ts(2322)
  }
} 

@swyxio
Copy link
Collaborator

swyxio commented Feb 2, 2020

i see you @RiaanWest. wanna PR something?

@ferdaber
Copy link
Collaborator

ferdaber commented Feb 2, 2020

This will break LibraryManagedAttributes inference for that component. It will cause all of its props to be optional when creating JSX elements of that component.

export type IconSize = 'small' | 'regular' | 'medium' | 'large';

interface IconPropsInterface {
  icon: string;
  size?: IconSize;
}

export class Icon extends Component<IconPropsInterface> {
  static defaultProps: IconPropsInterface = {
    icon: '',
    size: 'regularrr',   <-- Throws: Type '"regularrr"' is not assignable to type '"small" | "regular" | "medium" | "large" | undefined'.ts(2322)
  }
}

const myIcon = <Icon /> // this will not throw an error even though `icon` is required,

@RiaanWest
Copy link

Thanks for pointing this out @ferdaber - great point. I wasn't aware of that!

bernssolg added a commit to bernssolg/My-React-Sample that referenced this pull request Feb 28, 2022
erinodev added a commit to erinodev/My-React-project that referenced this pull request Feb 28, 2022
petardev101 added a commit to petardev101/react that referenced this pull request Jun 4, 2022
supercrytoking added a commit to supercrytoking/react that referenced this pull request Jul 14, 2022
kevindavies8 added a commit to kevindavies8/react-full-stack-developer that referenced this pull request Aug 24, 2022
johnfrench3 pushed a commit to johnfrench3/react-Fronted-developer that referenced this pull request Sep 7, 2022
ericbrown2716 added a commit to ericbrown2716/react-stack-build-website that referenced this pull request Sep 29, 2022
peterjohnson4987 added a commit to peterjohnson4987/full-stack-developer-react that referenced this pull request Oct 3, 2022
renawolford6 pushed a commit to renawolford6/react-husky-website that referenced this pull request Oct 6, 2022
Yoshidayoshi23 added a commit to Yoshidayoshi23/react that referenced this pull request Oct 20, 2022
renawolford6 added a commit to renawolford6/react-dev-build-doc- that referenced this pull request Nov 10, 2022
coopfeathy added a commit to coopfeathy/cheatsheet that referenced this pull request Dec 4, 2022
dreamcoder75 added a commit to dreamcoder75/react-sample that referenced this pull request Jan 15, 2023
holyblock pushed a commit to holyblock/chart that referenced this pull request Feb 27, 2023
AIDevMonster added a commit to AIDevMonster/Awesome-React that referenced this pull request Jun 21, 2023
whiteghostDev added a commit to whiteghostDev/Awesome-React that referenced this pull request Aug 6, 2023
cedev935 added a commit to cedev935/React-TypeScript that referenced this pull request Sep 11, 2023
aleksandaralek added a commit to aleksandaralek/typescript-react-cheatsheet that referenced this pull request Oct 24, 2023
xbucks pushed a commit to xbucks/react-cheatsheets that referenced this pull request Oct 24, 2023
joyfulmagician added a commit to joyfulmagician/react that referenced this pull request Oct 25, 2023
KonohaBrain125 pushed a commit to KonohaBrain125/React-Typescript that referenced this pull request Oct 26, 2023
atsumi000105 added a commit to atsumi000105/typescript-cheatsheets-react that referenced this pull request Dec 8, 2023
secretsuperstar1109 added a commit to secretsuperstar1109/react-typescript-cheatsheets that referenced this pull request Dec 9, 2023
champion119 added a commit to champion119/react that referenced this pull request Jan 5, 2024
rising-dragon360 added a commit to rising-dragon360/react that referenced this pull request Mar 13, 2024
EugeneYoona added a commit to EugeneYoona/React_full_src that referenced this pull request Apr 10, 2024
fairskyDev0201 added a commit to fairskyDev0201/typescript-cheatsheet that referenced this pull request Apr 17, 2024
TechSolutionNinja added a commit to TechSolutionNinja/react that referenced this pull request May 27, 2024
alisenola added a commit to alisenola/react-cheatsheets that referenced this pull request May 29, 2024
LegendaryDev320 added a commit to LegendaryDev320/react that referenced this pull request Jun 5, 2024
kaleb0402 added a commit to kaleb0402/react that referenced this pull request Jul 18, 2024
Linda423 added a commit to Linda423/React that referenced this pull request Jul 31, 2024
tosky19941209 added a commit to tosky19941209/React that referenced this pull request Aug 7, 2024
touchsky941209 added a commit to touchsky941209/react-rebrand that referenced this pull request Aug 26, 2024
genie4viz pushed a commit to genie4viz/react that referenced this pull request Sep 2, 2024
hussammousa68 added a commit to hussammousa68/react that referenced this pull request Oct 13, 2024
gvweshg added a commit to gvweshg/React-TypeScript that referenced this pull request Oct 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants