Skip to content

I would like to share some pure function component type definitions with others #63

@GavinRay97

Description

@GavinRay97

I am not the best at Typescript, so this type may be off a little, but I noticed that when trying to make pure function components two things happened:

  1. The props gave a type error
  2. The TSX element autocomplete does not work correctly -- it does not realize that attributes on the TSX element are actually values to the props object

image

So with this typing, it allows you to pass an interface or a type as a parameter for props, and it will strongly type them in the arguments and on the TSX element for you:

import { RenderContext } from 'vue'
type Maybe<T> = T | undefined | null

type TsxComponent<Props> = (
  args: Partial<RenderContext<Props>> & {
    [k in keyof Props]: Maybe<Props[k]>
  }
) => VueTsxSupport.JSX.Element
interface LabelInputProps {
  name: string
  type: string
}

const LabeledInput: TsxComponent<LabelInputProps> = ({props}) => {
  return (
    <div>
      <p>{props.name}</p>
      <input type={props.type} />
    </div>
  )
}

tsx-types

A warning about this though:

This works through a hack, by copying the properties of the type you pass into TsxComponent<Props> into the argument definitions at the TOP LEVEL. Because the TSX Element seems to autocomplete the parameters as all top-level arguments instead of just props.

RenderContext<Props> adds the types to the { props } definitions, and then [k in keyof Props]: Maybe<T[Props]> adds them to the top-level as well so that they appear as autocomplete options in the TSX Element.

This makes them incorrectly appear as argument values outside of props when destructuring in the function parameters too.

tsx-types-2

If anyone knows how to make this type so that it shows up on the TSX element autocomplete but not in the top-level function params, please post ideas. I think this may not be possible since they have to share a single type definition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions