How can I use typescript to destructure from a complex type?

Steven Lu

Consider this use case: I have a React functional component that I'd like to implement with the props being destructured (for consistency with all the other components).

This is a checkbox which has two possible roles. If it is associated with the full amount of data, it can be interacted with, and if it is associated with limited data, it will display a name, but the elements cannot be interacted with.

This can be simply implemented by the use of two independent components, and I may just go with that approach, but I wonder about the extent to which it is possible to extend and flesh out an existing component in code in this way.

So, i'm starting with a checkbox component that takes this type for props:

export interface CheckboxProps {
  checked: boolean;
  id: string;
  disabled?: boolean;
  disabledTooltipLabel?: string;
  onChange: VoidFunction;
  labelOrientation?: CheckboxLabelOrientation;
  label?: string;
  className?: string;
}

With this destructuring for the props to start off the function component definition:

export const Checkbox: React.FunctionComponent<CheckboxProps> = ({
  checked,
  disabled,
  disabledTooltipLabel,
  id,
  onChange,
  labelOrientation = "left",
  label = "",
  className,
}) => {
...

and I'm hoping to extend this with minimal refactoring to allow me to feed in a much simplified input consisting solely of label, e.g. with a tweaked type. However now if I try to actually use this, the destructuring is impossible:

export interface CheckboxProps {                      
  checked: boolean;                                   
  id: string;                                         
  disabled?: boolean;                                 
  disabledTooltipLabel?: string;                      
  onChange: VoidFunction;                             
  labelOrientation?: CheckboxLabelOrientation;        
  label?: string;                                     
  className?: string;                                 
}                                                     
type CheckboxBarebones = Pick<CheckboxProps, "label">;
                                                      
export const Checkbox: React.FunctionComponent<       
  CheckboxBarebones | CheckboxProps                   
> = (props) => {           
  const { label } = props;                           
  if ("checked" in props) {                           
    var {                                             
      checked,                                        
      disabled,                                       
      disabledTooltipLabel,                           
      id,                                             
      onChange,                                       
      labelOrientation = "left",                      
      className,                                      
    } = props;                                        
  }
...                                                   

This might work in theory, but I get vars-on-top and a torrent of block-scoped-var eslint errors. Is there any kind of "lite" destructuring I could do? Even if I manually pull values out of the props, how could I even go about doing it cleanly if I want to use const?

Since this is so completely horrific, I kept working and came up with:

export const Checkbox: React.FunctionComponent<   
  Pick<CheckboxProps, "label"> | CheckboxProps    
> = (props) => {                                  
  const {                                         
    label,                                        
    checked,                                      
    disabled,                                     
    disabledTooltipLabel,                         
    id,                                           
    onChange,                                     
    labelOrientation = "left",                    
    className,                                    
  } = props as Partial<CheckboxProps>;           
...

This seems like an improvement, but it still has a type cast in it and cannot be directly destructured in arrow function parameter. Is there a way to avoid it? I like how this preserves a useful type contract for the function component's props, which is the important thing here.

Aleksey L.

You can keep the desired props type for consumers, but in the implementation define it as partial without casting:

const Checkbox: React.FC<Pick<CheckboxProps, "label"> | CheckboxProps> = ({
  label,
  checked,
  disabled,
  disabledTooltipLabel,
  id,
  onChange,
  labelOrientation = "left",
  className,
}: Partial<CheckboxProps>) => {
    return <>...</>;
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How can I destructure with a vector from a var

From Dev

How can I use Automapper to map this complex type

From Dev

How can I unpack (destructure) elements from a vector?

From Java

How can I pass a Scala UserDefinedFunction where output is a complex type (using StructType and StructField) to be used from Pyspark

From Dev

How can I use ffmpeg to add music to a video being built from individual images with -filter_complex?

From Dev

How can I declare a function returning a type from a Typescript-enabled library in Typescript

From Dev

How can I AJAX POST this complex type to my MVC action?

From Dev

How can I refactor a simple class member to a more complex type?

From Dev

How can I print a complex dictionary data type in Python?

From Dev

How can I inject a type into a function in Typescript?

From Dev

How can I check the value is of type in typescript?

From Dev

How can I inject a type into a function in Typescript?

From Dev

How can I use flexbox to achieve a complex, responsive HTML layout?

From Dev

How can I use Retrofit to POST a complex JSON parameter

From Dev

How can I use both filter and filter_complex with ffmpeg?

From Dev

How can I use commander (npm) with TypeScript?

From Dev

How can I use DOMStringMap in TypeScript?

From Dev

How can I use for .. of loops in TypeScript?

From Dev

How can I use typescript in Aptana Studio?

From Dev

How can I get values from a complex Json object?

From Dev

Can I use conditional generic to set a callback return type in typescript?

From Dev

How can I augment a typescript interface using a type exported from another .d.ts file?

From Dev

How can i register an open generic type with a complex type constraint in Simple Injector?

From Dev

How to use inheritance in a more complex type in Julia

From Dev

How can I specify a return type for a $http call with Typescript?

From Dev

How can I define a return type of void for a function in a Typescript interface?

From Java

How can I see the full expanded contract of a Typescript type?

From Dev

How can I define the return type of a lodash reduce function with Typescript?

From Dev

Typescript - How can I conditionally define a type based on another property

Related Related

  1. 1

    How can I destructure with a vector from a var

  2. 2

    How can I use Automapper to map this complex type

  3. 3

    How can I unpack (destructure) elements from a vector?

  4. 4

    How can I pass a Scala UserDefinedFunction where output is a complex type (using StructType and StructField) to be used from Pyspark

  5. 5

    How can I use ffmpeg to add music to a video being built from individual images with -filter_complex?

  6. 6

    How can I declare a function returning a type from a Typescript-enabled library in Typescript

  7. 7

    How can I AJAX POST this complex type to my MVC action?

  8. 8

    How can I refactor a simple class member to a more complex type?

  9. 9

    How can I print a complex dictionary data type in Python?

  10. 10

    How can I inject a type into a function in Typescript?

  11. 11

    How can I check the value is of type in typescript?

  12. 12

    How can I inject a type into a function in Typescript?

  13. 13

    How can I use flexbox to achieve a complex, responsive HTML layout?

  14. 14

    How can I use Retrofit to POST a complex JSON parameter

  15. 15

    How can I use both filter and filter_complex with ffmpeg?

  16. 16

    How can I use commander (npm) with TypeScript?

  17. 17

    How can I use DOMStringMap in TypeScript?

  18. 18

    How can I use for .. of loops in TypeScript?

  19. 19

    How can I use typescript in Aptana Studio?

  20. 20

    How can I get values from a complex Json object?

  21. 21

    Can I use conditional generic to set a callback return type in typescript?

  22. 22

    How can I augment a typescript interface using a type exported from another .d.ts file?

  23. 23

    How can i register an open generic type with a complex type constraint in Simple Injector?

  24. 24

    How to use inheritance in a more complex type in Julia

  25. 25

    How can I specify a return type for a $http call with Typescript?

  26. 26

    How can I define a return type of void for a function in a Typescript interface?

  27. 27

    How can I see the full expanded contract of a Typescript type?

  28. 28

    How can I define the return type of a lodash reduce function with Typescript?

  29. 29

    Typescript - How can I conditionally define a type based on another property

HotTag

Archive