1
votes

I have a Vue project in which I created a new and plain TypeScript file Validation.ts:

import Vue from 'vue';
import BaseInput from '@/components/base/BaseInput.vue';

class ValidationService extends Vue {
  validateFields(fields: BaseInput[]): boolean {
    return this.$store.state.skipValidation || fields.map(field => field.validate()).every(Boolean);
  }
}

export default new ValidationService();

My class BaseInput has the public method validate() (which I'm able to call successfully from within other Vue components). But TypeScript now complains because it can't find the BaseInput class. When I try to follow the import I end up in the shims-vue.d.ts file.

How can I properly import a Vue component from outside a .vue file? Or is there a better solution to provide Vue with some global TypeScript methods then defining them in a plain .ts file?

1

1 Answers

3
votes

A .vue file contains a lot of things : a template part, a script part and a style part ... and typescript don't know how to handle that. A component is not made to be imported in a service, it's made to display/render something and it's definitely not made to define a type.

What you need to define a type or an interface in a separate file let' say ./models/input.ts where you can define your inputs types

export interface IBaseInput {
    name: string;
    ...
    ...
}
export interface IComplexInput {
    name: string;
    ...
    ...
}

I like to prefix my interfaces with an "I", but some people say you shouldn't (that's up to you)

then in your component .vue

import { IBaseInput } from './models/input.ts'
class BaseInput extends Vue implements IBaseInput {
    ...
}

and in your Service

import { IBaseInput } from './models/input.ts'
class ValidationService extends Vue {
  validateFields(fields: IBaseInput[]): boolean {
    return this.$store.state.skipValidation || fields.map(field => field.validate()).every(Boolean);
  }
}