vue-tsx-support
vue-tsx-support copied to clipboard
I would like to share some pure function component type definitions with others
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:
- The props gave a type error
- 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
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>
)
}
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.
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.
I had a similar problem, but with attrs
instead of props
. I wanted to create a render helper function for tests that would accept a component and its attrs
as arguments, and be type-safe. Didn't solve it, unfortunately.