feat(types): support inferring attrs
Related
- #3452
- #5423
- #6528
- #7546
- #7981
- #8264
- #8508
- #8620
- #8902
- #9272
RFC
- https://github.com/vuejs/rfcs/pull/477
Specific scenes
1. Wrapping an html element
import { defineComponent, type ImgHTMLAttributes, type AttrsType } from 'vue';
const MyImg = defineComponent({
props: {
foo: String
},
attrs: Object as AttrsType<ImgHTMLAttributes>,
created() {
this.$attrs.class // any
this.$attrs.style // StyleValue | undefined
this.$attrs.onError // ((payload: Event) => void) | undefined
this.$attrs.src // string | undefined
},
render() {
return <img {...this.$attrs} />
}
});
<MyImg class={'str'} style={'str'} src={'https://xxx.com/aaa.jpg'} onError={(e) => {
e; // Event
}}/>;
2. Wrapping a Vue component
import { defineComponent, type AttrsType } from 'vue';
const Comp = defineComponent({
props: {
foo: String
},
emits: {
baz: (val: number) => true
},
render() {
return <div>{this.foo}</div>
}
});
const MyComp = defineComponent({
props: {
bar: Number
},
attrs: Object as AttrsType<typeof Comp>,
created() {
this.$attrs.class // unknown
this.$attrs.style // unknown
this.$attrs.onBaz; // ((val: number) => any) | undefined
this.$attrs.foo; // string | undefined
},
render() {
return <Comp {...this.$attrs} />
}
});
<MyComp class={'str'} style={'str'} bar={1} foo={'str'} onBaz={(val) => {
val; // number
}} />;
Deploy Preview for vuejs-coverage failed.
| Name | Link |
|---|---|
| Latest commit | cc506ce99b1aa04c65522e8879fca9853fceed09 |
| Latest deploy log | https://app.netlify.com/sites/vuejs-coverage/deploys/63b5a24c5e5c910008a149fe |
Deploy Preview for vue-sfc-playground failed.
| Name | Link |
|---|---|
| Latest commit | cc506ce99b1aa04c65522e8879fca9853fceed09 |
| Latest deploy log | https://app.netlify.com/sites/vue-sfc-playground/deploys/63b5a24c075f5b0007a104a6 |
@yyx990803 we need this in oku-ui, for example we need to go back the
can you review and include this?
Looks great. Could you please rebase your branch to resolve conflicts?
I guess this feature will more be like defineSlots. Without adding runtime code, but adding only TS types.
Size Report
Bundles
| File | Size | Gzip | Brotli |
|---|---|---|---|
| runtime-dom.global.prod.js | 85.8 kB | 32.6 kB | 29.5 kB |
| vue.global.prod.js | 132 kB | 49.3 kB | 44.3 kB |
Usages
| Name | Size | Gzip | Brotli |
|---|---|---|---|
| createApp | 47.9 kB | 18.8 kB | 17.2 kB |
| createSSRApp | 50.6 kB | 19.9 kB | 18.2 kB |
| defineCustomElement | 50.3 kB | 19.6 kB | 17.9 kB |
| overall | 61.2 kB | 23.7 kB | 21.6 kB |
I would love to see this feature merged as well, and seeing as it's a typing only feature, I would love to see it show up in 2.7 as well. Currently creating a component that thinly wraps another component is pretty tedious, because you have to either redeclare all inner component props on the wrapper component, or you have to sacrifice type safety/intellisense.
I would love to see this feature merged as well, and seeing as it's a typing only feature, I would love to see it show up in 2.7 as well. Currently creating a component that thinly wraps another component is pretty tedious, because you have to either redeclare all inner component props on the wrapper component, or you have to sacrifice type safety/intellisense.
Nice call. It will be released in the future. Here is the Merge Request about this feature of Vue2. Also, you can use vue-ts-utils for workaround in the Vue2 or Vue3. If you have any questions about vue-ts-utils package, please let me know it and I would love to fix it. @Aaron-Pool
@rudyxu1102 Thanks for the PR
Managed to test your PR
It works with defineComponent(TS/TSX) way
But in .vue(SFC) useAttrs does not accept any argument/generics
const attrs = useAttrs<{ // Expected 0 type arguments, but got 1.
bar: string
}>()
Could you please REBASE your branch due the minor branch has been also rebased.
Could you please REBASE your branch due the minor branch has been also rebased.
@sxzz done
This is much needed, thanks!