-
-
Notifications
You must be signed in to change notification settings - Fork 442
fix(docs): extend vue 2 info regarding types #750
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
Conversation
If you don't care about the component props / events type-check and auto-complete in template, Could you mention this? |
I'm trying to say that this already works. Check the simple https://github.com/rchl/volar-vue2-test project for example. I know that using Composition API works better in terms of type support but I just can't understand why do you keep saying that EDIT: I've also added a simple method which requires annotation since the argument can't be inferred automatically. |
But that's not related to whether someone is using |
Without So user only have 3 option in future:
|
Seems to be working with So to conclude:
With that said, is there anything you want me to change in this PR? |
@rchl emmmm it's vetur report. :S |
Maybe Tutorial.vue is still |
No, you can try yourself on the project. Pushed Vue.extend removal |
Sorry, also need |
OK, can reproduce that case. That complicates things since now we have more variables to potentially document. As far as using plain JS, As far as TS, are you saying that it will work only with |
I think we don’t need to advise users what to use, just state the facts, which methods are supported and which are not.
|
You can try: // test-js.js
import Vue from 'vue'
Vue.extend({
data: () => ({
foo: 123
}),
mounted() {
this.foo // any
},
}) // test-ts.ts
import Vue from 'vue'
Vue.extend({
data: () => ({
foo: 123
}),
mounted() {
this.foo // number
},
}) |
I would swear that JS was working before but it doesn't seem like it. Maybe I was confused due to my Vetur running again... In that case I would say that Options API Vue2 support is not in a state that is usable in a real world projects so maybe it shouldn't be supported/advertised at all? Having to add The other issue is that type checking is spotty at best so many of the issues wouldn't be caught. Vetur is not ideal either, mind you, but certainly more complete. |
I think this has not relate to vetur/volar because it is reproduced in vanilla js/ts.
With defineComponent from
Users only need to continue to use vetur. If they don't want to modify the code, they don't have to switch to volar.
Are you talking about using Vue.extend? If yes, it is because vetur has done some work outside of Vue.extend to support more types. But like I said, doing so destroys predictability, so Volar won't do it. The component type will be completely controlled by the vue library. If Vue.extend is missing the props type, the user should not get the props type in the template, otherwise it is a bug for volar. |
But I'm talking about the Options API specifically. Can |
Yes, it is comprehensively better than Vue.extend. |
25798c7
to
87e1627
Compare
9f58be3
to
560b89b
Compare
hello, i have seen this property table for prop type check. |
@yangHeavy it's a example what you can define in class component for volar. export default class Foo extends Vue {
static components: {
MyComp: typeof MyComp
}
$props!: {
optionalProp?: string;
requiredProp: string;
}
$emit!: {
(e: 'my-event-1'): void
(e: 'my-event-2', arg1: string, arg2: number): void
}
$scopedSlots!: { // $scopedSlots for vue2, $slots for vue3
'my-slot-1': () => VNode[]
'my-slot-2': (bindings: { arg1: string, arg2: number }) => VNode[]
}
} |
@johnsoncodehk Thanks for answer for how to use class component with volar. But there some problems too. |
@yangHeavy yes you need to define it repeatedly. decorator == no TS support :) |
@johnsoncodehk I see. But there are some problems when I have defined the variable. |
@yangHeavy in this case you need to define |
@johnsoncodehk Sorry, I found it. I try it success!! I will share Volar with my colleagues and weigh whether we need to use variable type checking in cases where we need to define it twice. Thank you very much. |
@yangHeavy as a workaround, you could shim the component type to auto define In this workaround, you need to write @Component({})
class HelloWorld extends Vue {
@Prop() readonly requiredProp!: string;
@Prop() readonly optionalProp?: string;
nonProp?: string;
}
export default HelloWorld as ShimComponentProps<typeof HelloWorld>;
/** equal to
@Component({})
class HelloWorld extends Vue {
@Prop() readonly requiredProp!: string;
@Prop() readonly optionalProp?: string;
nonProp?: string;
$props!: {
requiredProp: string,
optionalProp?: string
}
}
*/ helper types: type ShimComponentProps<T extends new (...args: any) => any> = new () => InstanceType<T> & {
$props: ComponentProps<InstanceType<T>>
};
type ComponentProps<T> =
{ [K in keyof Pick<T, ReadonlyKeys<T> & OptionalKeys<T>>]?: T[K] }
& { [K in keyof Pick<T, ReadonlyKeys<T> & RequiredKeys<T>>]: T[K] };
type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
type ReadonlyKeys<
T,
U extends Readonly<T> = Readonly<T>,
K extends keyof T = keyof T
> = K extends keyof T ? Equal<Pick<T, K>, Pick<U, K>> extends true ? K : never : never;
type OptionalKeys<T> = keyof {
[K in keyof T as T[K] extends Required<T>[K] ? never : K]: T[K]
};
type RequiredKeys<T> = keyof {
[K in keyof T as T[K] extends Required<T>[K] ? K : never]: T[K]
}; |
@johnsoncodehk I think the reason is interface |
* master: (134 commits) Document recursive components (#1008) refactor: move common TS logic to new package `@volar/vue-typescript` (#1004) chore: update pnpm-lock.yaml v0.32.1 chore: changelog feat: show vite app preview config file fix: vite icon do not show with first editor fix: document symbols confusion between `<script>` and `<script setup>` feat: support generic props events fix: pug last child tag mapping incorrect chore: set minimal vscode version to 1.61.0 fix: auto-import cache logic break langauge server if TS version < 4.4 fix: exclude recursive component type if duplicate name with import components chore: update pnpm-lock.yaml fix: `source.organizeImports` not working in `editor.codeActionsOnSave` fix: slot name mapping range incorrect v0.32.0 chore: changelog feat: experimental webview features fix: don't pack extension with `--minify` flag which break scss formatting ...
I've applied your suggestion with some minor changes. Let me know if it looks better now. |
LGTM, thank you! |
In vue2 project, the type of scope parameter is deduced as vnode [] | undefined, I want to know what happened in the middle, or does it not have this feature? |
https://github.com/johnsoncodehk/volar/tree/master/extensions/vscode-vue-language-features I followed the steps prompted in the document and found that the type overload of Vue needs to be deleted. The slot parameter type prompt of volar can take effect |
@johnsoncodehk I was able to follow your instructions and get the type checking for Props and ScopedSlots working, but for the Emit, it seems like there might be a type mismatch. In the Vue types package, it looks like $emit expects a Function type. Should we override a different variable other than $emit instead? |
@aziztitu Vue 2 do not support typed emit, if you do want to, you can try omit |
@johnsoncodehk Gotcha. I was able to at least get the Event suggestions working by hacking it like this: This stops any errors from being thrown, but the only issue is there's no actual type checking happening. It seems to think that all events now take 2 args :D But it probably is just due to the fact that it's using the args from the last match. I can just remove the args from the Emit type, and live with it for now :) |
I know this puts the instructions upside-down since you've been suggesting to remove
Vue.extend
while I've changed it to recommendVue.extend
. The rationale is that, based on testing and as stated in the comments in #741,Vue.extend
is really the way to go to fix the inevitable type issues in Vue 2 projects and I haven't really found any downsides to it.If you have any specific examples where
Vue.extend
would makes things worse type-wise then I can tweak the wording or change it completely.Note that when working with Vetur, I'm used to having to help the type system in many situations by adding manual JSDoc comments (when using JS) so I would expect this to be the case with Volar also. But that shouldn't change the fact that
Vue.extend
is required in the first place.Related #741