Pesquisa de site

javascript - Importar componente Vue em arquivo TypeScript puro falha


Eu tenho um projeto Vue no qual criei um novo arquivo TypeScript simples 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();

Minha classe BaseInput tem o método público validate() (que consigo chamar com sucesso de outros componentes Vue). Mas o TypeScript agora reclama porque não consegue encontrar a classe BaseInput. Quando tento seguir o import, acabo no arquivo shims-vue.d.ts.

Como posso importar corretamente um componente Vue de fora de um arquivo .vue? Ou existe uma solução melhor para fornecer ao Vue alguns métodos globais em TypeScript do que defini-los em um arquivo .ts simples?

Resposta #1

Um arquivo .vue contém muitas coisas: uma parte de template, uma parte de script e uma parte de estilo... e o TypeScript não sabe como lidar com isso. Um componente não é feito para ser importado em um serviço, ele é feito para exibir/renderizar algo e definitivamente não é feito para definir um tipo.

O que você precisa é definir um tipo ou uma interface em um arquivo separado, digamos ./models/input.ts, onde você pode definir os tipos dos seus inputs

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

Eu gosto de prefixar minhas interfaces com um "I", mas algumas pessoas dizem que você não deveria (isso depende de você)

então no seu componente .vue

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

e no seu Serviço

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);
  }
}

Artigos relacionados