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

Cross file template type checking - check that components are passed props with the correct types #1596

Closed
octref opened this issue Dec 19, 2019 · 5 comments

Comments

@octref
Copy link
Member

octref commented Dec 19, 2019

When one has a Vue file:

<script>
export default {
  name: 'Foo',
  props: { bar: String }
}
</script>

Such templates should show error:

<foo :bar="5"></foo>
<foo :bar="myNumber"></foo>

Currently we have:

interface ComponentData<T> {
  props: Record<string, any>;
  on: ComponentListeners<T>;
  directives: any[];
}

I'm wondering if we could do something like this. For each imported Vue component, generate its corresponding type definition such as:

interface CProp1 {
  msg: string;
  [other: string]: any;
}
interface ComponentData1<T> {
  props: CProp1;
  on: ComponentListeners<T>
  directives: any[]
}
export declare const __vlsComponentHelper1: {
  <T>(vm: T, tag: string, data: ComponentData1<Record<string, any>> & ThisType<T>, children: any[]): any
}

Then the virtual file with this content would complain:

__vlsComponentHelper1(this, 'foo', { props: { msg: 5 }, on: {}, directives: [] }, []) // Type 'number' is not assignable to string

It should be easy to translate the props interface:

  • If required: false is specified, translate to msg?: type. Otherwise translate to msg: type
  • type is inferred from constructor types. For example String -> string. If uninferrable, use any.

@ktsn What do you think?

@ktsn
Copy link
Member

ktsn commented Dec 19, 2019

Looks good for Vue 2. We can reuse component props type in Vue 3 as required is handled if I remember correctly.

@mesqueeb
Copy link

mesqueeb commented Jan 22, 2020

My preferred syntax would be close to the native PropType:

props: {
  userList: {
    type: Array as PropType<User[]>,
    default: () => []
  },
  category: {
    type: String as PropType<MY_ENUM>,
    required: true
  }
}

Having to define the prop types outside of the actual place you write the props, it would be less ideal in my opinion.

Also anything that stays closest to regular Vue syntax seems best for me. 😉

@ktsn
Copy link
Member

ktsn commented Jan 22, 2020

@mesqueeb We are talking about auto generated (probably virtual) type declaration for Vetur which the end users won't see / edit. I believe a simple interface type derived from Vue component's props option is enough to utlize it in template type checking.

@mesqueeb
Copy link

@ktsn Aha! I had originally posted my question in the VTI feedback thread, but was redirected here...

My question was:

"Will it be possible for VTI to catch TypeScript type errors by annotating types via eg. myProp: Object as PropType<MyType>?"

@ktsn
Copy link
Member

ktsn commented Jan 22, 2020

Yes, it will be possible! We already have rough idea to achieve it.

@octref octref changed the title Cross file template type checking Cross file template type checking - check that components are passed props with the correct types Aug 8, 2020
@octref octref closed this as completed in 021fa20 Sep 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants