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

[QUESTION] How to allow HTML attributes as props while using Typescript JSX? #3452

Closed
axelthat opened this issue Mar 20, 2021 · 3 comments · May be fixed by #7444
Closed

[QUESTION] How to allow HTML attributes as props while using Typescript JSX? #3452

axelthat opened this issue Mar 20, 2021 · 3 comments · May be fixed by #7444

Comments

@axelthat
Copy link

Version

3.0.7

Reproduction link

https://github.com/sanjade/vue3-bug

Steps to reproduce

First of all, I know this kind of issue shouldn't be asked here but I just wanted to tell you that I did try asking the question in StackOverflow. However it has no response and it's been 2 days.

- git clone https://github.com/sanjade/vue3-bug
- cd vue3-bug && yarn
- Goto `App.tsx` and you will see the error in `type` attribute

What is expected?

Suppose I have this input component:

// components/input.tsx

import { defineComponent } from "@vue/runtime-core"

export default defineComponent({
    inheritAttrs: false,
    setup(props, { attrs }) {
        return () => (
            <div>
                <input type="text" {...attrs} />
            </div>
        )
    }
})

Now, I use this component like so and provide type="password" attribute:

// App.tsx

import { defineComponent } from "@vue/runtime-core"
import Input from "./components/input"

export default defineComponent({
    setup(props, { attrs }) {
        return () => <Input type="password"></Input>
    }
})

I expect Typescript not to throw any error.

What is actually happening?

But Typescript complains in App.tsx:

(JSX attribute) type: string
Type '{ type: string; }' is not assignable to type 'IntrinsicAttributes & Partial<{}> & Omit<Readonly<{} & {}> & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>'.
  Property 'type' does not exist on type 'IntrinsicAttributes & Partial<{}> & Omit<Readonly<{} & {}> & VNodeProps & AllowedComponentProps & ComponentCustomProps, never>'.ts(2322)

How do you specify that InputHTMLAttributes are also allowed as props in the input.tsx component?

@HcySunYang
Copy link
Member

You can use functional components for that purpose

import { FunctionalComponent } from 'vue'

const MyInput: FunctionalComponent<InputHTMLAttributes & { foo?: string}> = (props) => {
  return <input {...props}/>
}

const el = <MyInput foo="str" autofocus type="xxx"  />

For defineComponent, it needs to be improved, this is related RFC vuejs/rfcs#281. BTW, you can ask questions on the forum, the Discord server or StackOverflow.

@agileago
Copy link

agileago commented Apr 10, 2021

image

when i define functional component props it will display type errors

TS2322: Type '{ p1: StringConstructor; p2: NumberConstructor; onP1: { type: FunctionConstructor; }; }' is not assignable to type 'ComponentPropsOptions<FuncCompProps> | undefined'.   Types of property 'onP1' are incompatible.     Type '{ type: FunctionConstructor; }' is not assignable to type 'Prop<() => void, () => void> | null | undefined'.       Types of property 'type' are incompatible.         Type 'FunctionConstructor' is not assignable to type 'true | PropType<() => void> | null | undefined'.           Type 'FunctionConstructor' is not assignable to type '() => () => void'.             Type 'Function' is not assignable to type '() => void'.               Type 'Function' provides no match for the signature '(): void'.
import { defineComponent, FunctionalComponent } from 'vue'

interface FuncCompProps {
  p1: string
  p2: number
  onP1(): void
}
const FuncComp: FunctionalComponent<FuncCompProps> = (props, ctx) => {
  return <div>{props.p1}</div>
}
FuncComp.inheritAttrs = false
FuncComp.displayName = 'Func'
FuncComp.props = {
  p1: String,
  p2: Number,
  onP1: {
    type: Function,
  }
}

and i want to define stateful component like a union one style. the below code is

interface StateFulCompProps {
  s1: string
  s2: number
  onS1(): void
}

const StateFulComp = defineComponent<StateFulCompProps>((props, ctx) => {
  return () => <div>{props.s1}</div>
})
StateFulComp.inheritAttrs = false
StateFulComp.displayName = 'StateFulComp'
StateFulComp.props = {
  s1: String,
  s2: Number,
  onS1: Function,
}

in webstorm ide has some mistakes

  • the functinal props type will display right. but stateful props type display error
    image
    image

  • the stateful component props will change optional (string | undefined)

how can i explicit declare the component props type in stateful coponent ?

@HcySunYang thanks

@rudyxu1102
Copy link
Contributor

@github-actions github-actions bot locked and limited conversation to collaborators Sep 16, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants