- The TypeScript series ? shows how to use the Declare Module syntax with vue3 examples [? Module Declaration]
- Past directory
- Usage scenarios
- Let vue3 support this.$axios
- A more comprehensive example
- Type extension for non-TS/JS file modules
- vuex
- Not the whole story
- WeChat group
- github
- Поддержка TypeScript
- Официальные файлы объявлений в npm-пакетах
- Рекомендуемая конфигурация
- Инструменты разработки
- Создание проекта
- Поддержка редакторов
- Использование
- Компоненты Vue на основе классов
- Расширение типов для использования с плагинами
- Аннотации возвращаемых типов
- Аннотация типов входных параметров
The TypeScript series ? shows how to use the Declare Module syntax with vue3 examples [? Module Declaration]
This series article is I 20 years began to write, this module statement is also the last lesson of this series, the middle because of the time interval of 1 year, at that time promised everyone to supplement, now to pay off the debt ?.
In the middle of the time I wrote vue3 introductory tutorial, now write half, with video, if a friend in need can go to look at. www.yuque.com/books/share. «Selected Knowledge points» of VUE3
Past directory
Usage scenarios
The «package» downloaded by NPM comes with a declaration file. If we need to extend its type declaration, we can use the «Declare Module» syntax.
Let vue3 support this.$axios
// main.ts app.config.globalProperties.$axios = axios; Copy the code
Functionally we implement «this. axios», but ts does not automatically infer that we added axios», so we add the following declaration file:
// global.d.ts import < ComponentCustomProperties >from 'vue' // The instance type of axios import < AxiosInstance >from 'axios' // Declare the extension to @vue/ run-time core package. / / expansion "ComponentCustomProperties" interface here, because he is the instance of vue3 attribute type. declare module '@vue/runtime-core' < // Provide the type for 'this.$HTTP' interface ComponentCustomProperties < $axios: AxiosInstance; >>Copy the code
Expansion of «ComponentCustomProperties» interface here, because he is in vue3 instance of the type of the property.
A more comprehensive example
In the example above we extend the interface in the original declaration, but what if the export is a Class? The default export for «any-touch» is a Class. Suppose we make the following changes to the «any-touch» code:
- Export adds «AAA» variable, which is string.
- Class instance adds the «BBB» attribute, which is of type number.
- Class adds the static attribute «CCC «, which is a function.
// global.d.ts // AnyTouch must import, because only import is an extension, not import will become an overwrite. import AnyTouch from 'any-touch' declare module 'any-touch' < // Export adds the "aaa" variable, which is a string. export const aaa: string; export default class < // Class adds a static attribute "CCC ", which is a function. static ccc:() = void // Add a "BBB" attribute to an instance of the class, which is type number. bbb: number>>Copy the code
Note: AnyTouch must import, because only an import is a type extension, otherwise it becomes an overwrite.
Under test, the types have been added correctly:
// index.ts import AT, from 'any-touch'; const s = aaa.substr(0.1); const at = new AT(); at.bbb = 123; AT.ccc = () = <>; Copy the code
Type extension for non-TS/JS file modules
Ts only supports importing and exporting modules, but sometimes you may need to import CSS/HTML files. In this case, you need to use wildcards to make TS regard them as modules. Here is the import support for «.
// global.d.ts declare module '*.vue' < import < DefineComponent >from 'vue' const component: DefineComponent<>, <>, any export default component > Copy the code
// App.vue // Can recognize vue files import X1 from './X1.vue'; export default defineComponent(< components: >) Copy the code
Declare the vue file as a module and note that the default export of the module is of type «Component». This allows the registration module to correctly identify the type in the Components field of the Vue.
vuex
$store = $store = $store = $store = $store = $store = $store = $store
// vuex.d.ts import < ComponentCustomProperties >from 'vue' import < Store >from 'vuex' // Declare the extension to @vue/ run-time core package declare module '@vue/runtime-core' < // declare your own store states interface State < count: number > // provide typings for `this.$store` interface ComponentCustomProperties < $store: StoreState > > Copy the code
Not the whole story
This is the end of the declaration, but there are still some «module declaration» ways are not covered, because the ultimate goal of this course is vue3 based development does not involve NPM package development, so the rest of the content will not be expanded, if you need to see the TS documentation to learn, with the basis of this article, I’m sure you’ll learn more easily.
WeChat group
Thank you for your reading. If you have any questions, you can add me to the wechat group, and I will pull you into the wechat group (Because Tencent limits the number of wechat groups to 100, when the number exceeds 100, you must be joined by group members).
github
My own open source is based on TS, please visit github.com/any86
Поддержка TypeScript
Vue CLI предоставляет встроенную поддержку TypeScript.
Официальные файлы объявлений в npm-пакетах
Статическая типизация может предотвратить много потенциальных ошибок ещё на этапе компиляции, особенно при разрастании приложений. По этой причине Vue поставляется с официальными файлами объявления типов TypeScript, причём не только для ядра Vue, но также и для Vue Router и Vuex.
Так как всё это уже опубликовано на npm, то вам даже не понадобится использовать внешние инструменты, такие как Typings , потому что объявления типов автоматически импортируются вместе с Vue.
Рекомендуемая конфигурация
// tsconfig.json
{
"compilerOptions": {
// это соответствует поддержке браузеров у Vue
"target": "es5",
// это обеспечивает более строгий вывод для свойств данных в `this`
"strict": true,
// при использовании webpack 2+ или rollup, добавить поддержку tree-shaking:
"module": "es2015",
"moduleResolution": "node"
}
}
Обратите внимание, вы должны включить strict: true (или, по крайней мере, noImplicitThis: true , которая является частью флага strict ), чтобы использовать проверку типов у this в методах компонентов, иначе он всегда будет рассматриваться как тип any .
Инструменты разработки
Создание проекта
Vue CLI 3 позволяет генерировать новые проекты, которые используют TypeScript. Чтобы начать:
# 1. Установите Vue CLI, если она ещё не установлена
npm install --global @vue/cli
# 2. Создайте новый проект, затем выберите опцию «Manually select features»
vue create my-project-name
Поддержка редакторов
Для разработки приложений Vue с использованием TypeScript мы настоятельно рекомендуем использовать Visual Studio Code, которая предоставляет отличную встроенную поддержку для TypeScript. Если вы используете однофайловые компоненты, воспользуйтесь отличным расширением Vetur, которое обеспечивает вывод TypeScript внутри однофайловых компонентов и многие другие возможности.
WebStorm также предоставляет встроенную поддержку для TypeScript и Vue.
Использование
Чтобы позволить TypeScript правильно выводить типы внутри опций компонента Vue, вам необходимо определять компоненты с помощью Vue.component или Vue.extend :
import Vue from 'vue'
const Component = Vue.extend({
// вывод типов включён
})
const Component = {
// это НЕ БУДЕТ работать,
// потому что TypeScript не может определить, что это опции компонента Vue.
}
Компоненты Vue на основе классов
Если вы предпочитаете API на основе классов при объявлении компонентов, вы можете использовать официально поддерживаемый декоратор vue-class-component:
import Vue from 'vue'
import Component from 'vue-class-component'
// декоратор @Component указывает, что класс — это компонент Vue
@Component({
// здесь можно использовать все опции компонента
template: ''
})
export default class MyComponent extends Vue {
// Данные инициализации могут быть объявлены как свойства экземпляра
message: string = 'Hello!'
// Методы компонента могут быть объявлены как методы экземпляра
onClick (): void {
window.alert(this.message)
}
}
Расширение типов для использования с плагинами
Плагины могут добавлять во Vue новые глобальные свойства, свойства экземпляра и параметры компонента. В этих случаях необходимы объявления типов для возможности плагина компилироваться в TypeScript. К счастью, есть функция TypeScript для расширения существующих типов, называемая расширением модуля (module augmentation).
Например, чтобы объявить свойство экземпляра $myProperty с типом string :
// 1. Обязательно импортируйте Vue перед объявлением расширенных типов
import Vue from 'vue'
// 2. Укажите файл с типами, которые вы хотите расширить
// Vue имеет тип конструктора в types/vue.d.ts
declare module 'vue/types/vue' {
// 3. Объявите расширение для Vue
interface Vue {
$myProperty: string
}
}
После включения указанного выше кода в файл объявлений (например, my-property.d.ts ) в вашем проекте, вы можете использовать $myProperty в экземпляре Vue.
var vm = new Vue()
console.log(vm.$myProperty) // Это скомпилируется без ошибок
Вы также можете объявить дополнительные глобальные свойства и параметры компонента:
import Vue from 'vue'
declare module 'vue/types/vue' {
// Глобальные свойства можно объявлять
// на интерфейсе `VueConstructor`
interface VueConstructor {
$myGlobal: string
}
}
// ComponentOptions объявляется в types/options.d.ts
declare module 'vue/types/options' {
interface ComponentOptionsextends Vue> {
myOption?: string
}
}
Указанные выше объявления позволяют скомпилировать следующий код:
// Глобальное свойство
console.log(Vue.$myGlobal)
// Дополнительный параметр компонента
var vm = new Vue({
myOption: 'Привет'
})
Аннотации возвращаемых типов
TypeScript может столкнуться с трудностями при определении типов определённых методов из-за циклической природы файлов Vue с объявлением типов. По этой причине вам может потребоваться аннотировать возвращаемый тип для методов, таких как render и тех, которые находятся в computed .
import Vue, { VNode } from 'vue'
const Component = Vue.extend({
data () {
return {
msg: 'Привет'
}
},
methods: {
// необходима аннотация из-за `this` в возвращаемом типе
greet (): string {
return this.msg + ', мир'
}
},
computed: {
// необходима аннотация
greeting (): string {
return this.greet() + '!'
}
},
// `createElement` выводится, но `render` нуждается в возвращаемом типе
render (createElement): VNode {
return createElement('div', this.greeting)
}
})
Если вы обнаружите, что вывод типа или автодополнение не работают, аннотация некоторых методов может помочь решить эти проблемы. Использование опции —noImplicitAny поможет найти многие из этих методов без аннотаций.
Аннотация типов входных параметров
import Vue, { PropType } from 'vue'
interface ComplexMessage {
title: string,
okMessage: string,
cancelMessage: string
}
const Component = Vue.extend({
props: {
name: String,
success: { type: String },
callback: {
type: Function as PropType() => void>
},
message: {
type: Object as PropTypeComplexMessage>,
required: true,
validator (message: ComplexMessage) {
return !!message.title;
}
}
}
})
Если функция валидатора не получает выведенный тип или не работает автоподстановка свойств, то аннотация аргумента с ожидаемым типом может помочь решить эти проблемы.
Обнаружили ошибку или хотите добавить что-то своё в документацию? Измените эту страницу на GitHub! Опубликовано на Netlify .