在 TypeScript Quasar 引导文件中扩展 Vue 实例接口
Extending Vue instance interface in TypeScript Quasar boot file
编辑:我在下面的 post 中多次说过我“不在模块中”。任何时候一个文件中的 JavaScript 代码被另一个从技术上讲是模块的文件调用。我想说的是,这个模块在脚本初始化时由 Quasar 自动调用,预计会产生全局副作用。该模块从未导入到我编写的任何代码中。
简洁 post:
我正在使用支持 TypeScript 和 Vue Class 组件的 Quasar 2.0.0。我希望添加一个实例 属性 以便在我的 classes 中访问:this.$fetch(...);
我创建了一个引导文件,内容如下:
import Vue from "vue";
declare module "vue/types/vue"
{
interface Vue
{
prototype: {
$fetch: (resource: (string | Request), init?: RequestInit) => Promise<Response>
},
$fetch: (resource: (string | Request), init?: RequestInit) => Promise<Response>
}
}
type Context = {
Vue: Vue
};
export default async ({ Vue: vue }:Context) =>
{
vue.prototype.$fetch = async (resource, init) =>
{
return fetch(resource, init);
};
};
这不会引发 TypeScript 的任何错误。但是当我尝试在组件中使用它时,出现错误:
<template>
<q-layout>
<q-page-container>
<q-page class="flex flex-center">
<h1>Test</h1>
</q-page>
</q-page-container>
</q-layout>
</template>
<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
@Component
export default class TestPage extends Vue
{
mounted ()
{
this.$fetch("https://www.google.com");
}
}
</script>
Property '$fetch' does not exist on type 'TestPage'.
上一个(杂乱无章)post:
我正在开发 Quasar 应用程序,为了方便起见,我想创建一个修改后的 fetch
方法,如果请求的域与我的后端域匹配,它会注入我的 API 密钥.界面类似于:
@Component
export default class VueComponent extends Vue
{
mounted()
{
this.$fetch("https://www.example.com/api/endpoint").then(console.log);
}
}
我知道如何定义这样的东西。我只需要根据 https://vuejs.org/v2/cookbook/adding-instance-properties.html:
更新 Vue
原型
Vue.prototype.$fetch = async function(request, init)
{
// ... blah ...
};
根据 Quasar's documentation,更新 Vue 原型的正确时间是在 引导文件 中。所以我创建了一个:
quasar new boot fetch
我的引导文件开始时相当简单:
export default async ({ Vue }) =>
{
Vue.prototype.$fetch = async (resource, init) =>
{
return fetch(resource, init);
};
};
当我尝试转换为 TypeScript 时,一切都崩溃了。参数 Vue
隐式具有 any
类型,因为没有为参数对象提供类型。
我试过这样定义类型:
import Vue from "vue";
type Context = {
Vue: Vue
};
export default async ({ Vue }:Context) =>
然而,这引起了对变量阴影的抱怨(Vue
在上层范围中定义)。我注意到 Vue
变量的类型是 VueConstructor<Vue>
,所以我改为尝试:
import { VueConstructor } from "vue";
type Context = {
Vue: VueConstructor
};
export default async ({ Vue }:Context) =>
这适用于函数定义,但在 Vue.prototype.$fetch = ...
行上引发错误:“不安全的成员访问 .$fetch on any value”。 TypeScript 不希望 Vue.prototype
有 $fetch
属性。如果我正在做一个模块定义,我会像这样扩展接口:
declare module "abc" {
VueConstructor: {
prototype: {
$fetch: ...
}
}
}
但是我没有声明模块——这是一个引导文件。我尝试了一个快速的 hack 来解决这个问题,只在我的引导文件的上下文中定义我自己的 VueConstructor
:
interface VueConstructor
{
prototype: {
$fetch: (resource: (string | Request), init?: RequestInit) => Promise<Response>
}
}
type Context = {
Vue: VueConstructor
};
export default async ({ Vue }:Context) =>
{
Vue.prototype.$fetch = async (resource: (string | Request), init?: RequestInit) =>
{
return fetch(resource, init);
};
};
这终于让 TypeScript 停止抱怨 this 文件,但是当我尝试在一个文件中使用 this.$fetch
组件:
Property '$fetch' does not exist on type 'VueComponent'.
由于 VueComponent
扩展了 Vue
我想我需要更新 Vue
class 的定义,但我不知道如何做。我尝试将以下内容添加到我的引导文件中:
interface Vue
{
$fetch: (resource: (string | Request), init?: RequestInit) => Promise<Response>
}
但这没有用。我不能只使用 declare module
因为我不在模块中。如何在没有模块的情况下全局扩展类型?
我的“简洁 post”中的代码示例(展示了我在反复试验后得出的结论)确实有效——我只需要重新启动我的计算机(可能只需要重新启动我的 IDE 但由于某种原因点击关闭并没有完全关闭它)
编辑:我在下面的 post 中多次说过我“不在模块中”。任何时候一个文件中的 JavaScript 代码被另一个从技术上讲是模块的文件调用。我想说的是,这个模块在脚本初始化时由 Quasar 自动调用,预计会产生全局副作用。该模块从未导入到我编写的任何代码中。
简洁 post:
我正在使用支持 TypeScript 和 Vue Class 组件的 Quasar 2.0.0。我希望添加一个实例 属性 以便在我的 classes 中访问:this.$fetch(...);
我创建了一个引导文件,内容如下:
import Vue from "vue";
declare module "vue/types/vue"
{
interface Vue
{
prototype: {
$fetch: (resource: (string | Request), init?: RequestInit) => Promise<Response>
},
$fetch: (resource: (string | Request), init?: RequestInit) => Promise<Response>
}
}
type Context = {
Vue: Vue
};
export default async ({ Vue: vue }:Context) =>
{
vue.prototype.$fetch = async (resource, init) =>
{
return fetch(resource, init);
};
};
这不会引发 TypeScript 的任何错误。但是当我尝试在组件中使用它时,出现错误:
<template>
<q-layout>
<q-page-container>
<q-page class="flex flex-center">
<h1>Test</h1>
</q-page>
</q-page-container>
</q-layout>
</template>
<script lang="ts">
import { Vue, Component } from "vue-property-decorator";
@Component
export default class TestPage extends Vue
{
mounted ()
{
this.$fetch("https://www.google.com");
}
}
</script>
Property '$fetch' does not exist on type 'TestPage'.
上一个(杂乱无章)post:
我正在开发 Quasar 应用程序,为了方便起见,我想创建一个修改后的 fetch
方法,如果请求的域与我的后端域匹配,它会注入我的 API 密钥.界面类似于:
@Component
export default class VueComponent extends Vue
{
mounted()
{
this.$fetch("https://www.example.com/api/endpoint").then(console.log);
}
}
我知道如何定义这样的东西。我只需要根据 https://vuejs.org/v2/cookbook/adding-instance-properties.html:
更新Vue
原型
Vue.prototype.$fetch = async function(request, init)
{
// ... blah ...
};
根据 Quasar's documentation,更新 Vue 原型的正确时间是在 引导文件 中。所以我创建了一个:
quasar new boot fetch
我的引导文件开始时相当简单:
export default async ({ Vue }) =>
{
Vue.prototype.$fetch = async (resource, init) =>
{
return fetch(resource, init);
};
};
当我尝试转换为 TypeScript 时,一切都崩溃了。参数 Vue
隐式具有 any
类型,因为没有为参数对象提供类型。
我试过这样定义类型:
import Vue from "vue";
type Context = {
Vue: Vue
};
export default async ({ Vue }:Context) =>
然而,这引起了对变量阴影的抱怨(Vue
在上层范围中定义)。我注意到 Vue
变量的类型是 VueConstructor<Vue>
,所以我改为尝试:
import { VueConstructor } from "vue";
type Context = {
Vue: VueConstructor
};
export default async ({ Vue }:Context) =>
这适用于函数定义,但在 Vue.prototype.$fetch = ...
行上引发错误:“不安全的成员访问 .$fetch on any value”。 TypeScript 不希望 Vue.prototype
有 $fetch
属性。如果我正在做一个模块定义,我会像这样扩展接口:
declare module "abc" {
VueConstructor: {
prototype: {
$fetch: ...
}
}
}
但是我没有声明模块——这是一个引导文件。我尝试了一个快速的 hack 来解决这个问题,只在我的引导文件的上下文中定义我自己的 VueConstructor
:
interface VueConstructor
{
prototype: {
$fetch: (resource: (string | Request), init?: RequestInit) => Promise<Response>
}
}
type Context = {
Vue: VueConstructor
};
export default async ({ Vue }:Context) =>
{
Vue.prototype.$fetch = async (resource: (string | Request), init?: RequestInit) =>
{
return fetch(resource, init);
};
};
这终于让 TypeScript 停止抱怨 this 文件,但是当我尝试在一个文件中使用 this.$fetch
组件:
Property '$fetch' does not exist on type 'VueComponent'.
由于 VueComponent
扩展了 Vue
我想我需要更新 Vue
class 的定义,但我不知道如何做。我尝试将以下内容添加到我的引导文件中:
interface Vue
{
$fetch: (resource: (string | Request), init?: RequestInit) => Promise<Response>
}
但这没有用。我不能只使用 declare module
因为我不在模块中。如何在没有模块的情况下全局扩展类型?
我的“简洁 post”中的代码示例(展示了我在反复试验后得出的结论)确实有效——我只需要重新启动我的计算机(可能只需要重新启动我的 IDE 但由于某种原因点击关闭并没有完全关闭它)