【发布时间】:2021-12-07 21:51:09
【问题描述】:
将 VueJS 项目从 JavaScript + Options API 迁移到 TypeScript + Composition API,我逐渐找到了大多数东西的等价物。我正在努力解决的一件事是v-model 功能。我找到了一个good article on implementing it using Composition API,作者在其中创建了一个可组合的函数,该函数可以在想要实现v-model 的组件中重用。我现在正在尝试使用 TypeScript 编写一个等效函数。
这里是原始JS代码:
import { computed } from 'vue'
export function useModelWrapper(props, emit, name = 'modelValue') {
return computed({
get: () => props[name],
set: (value) => emit(`update:${name}`, value)
})
}
我的 TS 实现如下所示:
import { computed, ComputedRef } from '@vue/composition-api'
export function useModelWrapper<T> (props: Record<string, unknown>, emit: (event: string, value: T) => void, name: 'modelValue') : ComputedRef {
return computed({
get: () => props[name],
set: (value) => emit(`update:${name}`, <T>value)
})
}
这编译得很好,但 Vue 对此不太满意。我明白了
没有重载匹配这个调用
如果我在组件中使用此函数会出错。
我怀疑 TS 版本中 props 的类型不正确,但我无法弄清楚我应该在那里使用什么类型。我已经用Object、unknown 和any 进行了尝试,但它们都不允许我在getter 中执行props[name](any 可以,但是 TS 抱怨我不应该使用any 作为props 的类型)。
我在这里做错了什么?
编辑
这是完整的错误文本:
{
"resource": "../ProjectsDropdown.vue",
"owner": "_generated_diagnostic_collection_name_#6",
"code": "2769",
"severity": 8,
"message": "No overload matches this call.
Overload 1 of 3, '(options: ComponentOptionsWithoutProps<unknown, unknown, Data, {}, {}>): VueProxy<unknown, unknown, Data, {}, {}>', gave the following error.
Type '{ modelValue: PropType<Project>; }' is not assignable to type 'undefined'.
Overload 2 of 3, '(options: ComponentOptionsWithArrayProps<string, Data, Data, {}, {}, Readonly<{ [x: string]: any; }>>): VueProxy<Readonly<{ [x: string]: any; }>, Data, Data, {}, {}>', gave the following error.
Type '{ modelValue: PropType<Project>; }' is not assignable to type 'string[]'.
Object literal may only specify known properties, and 'modelValue' does not exist in type 'string[]'.
Overload 3 of 3, '(options: ComponentOptionsWithProps<ComponentPropsOptions<Data>, Data, Data, {}, {}, ({ [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; ... 32 more ...;
toLocaleString?: string | undefined; }) | ({} & { ...; })>): VueProxy<...>', gave the following error.
Type '{ modelValue: PropType<Project>; }' is not assignable to type 'ComponentPropsOptions<Data> | undefined'.
Types of property 'modelValue' are incompatible.
Type 'PropType<Project>' is not assignable to type 'Prop<unknown, unknown> | null | undefined'.
Type 'new (...args: never[]) => Project & object' is not assignable to type 'Prop<unknown, unknown> | null | undefined'.
Type 'new (...args: never[]) => Project & object' is not assignable to type 'new (...args: string[]) => Function'.
Types of parameters 'args' and 'args' are incompatible.
Type 'string' is not assignable to type 'never'.",
"source": "Vetur",
"startLineNumber": 59,
"startColumn": 16,
"endLineNumber": 119,
"endColumn": 3
}
编辑 2
这是我在组件中使用此函数的方式:
<script lang='ts'>
export default defineComponent({
...
import { useModelWrapper } from '../usemodelWrapper'
props: {
modelValue: Object as PropType<Project>
},
setup (props, { emit }) {
return {
selectedProject: useModelWrapper<Project>(props, emit, 'modelValue')
}
})
</script>
【问题讨论】:
-
这个方法是怎么调用的?
-
@Eldar:
props部分有一个属性modelValue: Object as PropType<Project>并且setup()函数返回的对象有一个成员selectedProject: useModelWrapper(props, emit, 'modelValue') -
我认为问题出在
, name: 'modelValue')部分。这是一个类型声明而不是默认值赋值。试试看name = 'modelValue') -
@Eldar:谢谢。试过了。仍然得到同样的错误。
-
请用您使用它的代码更新问题。这是最重要的部分,因为它会导致错误。如果您像评论中显示的那样使用它,问题是您没有使用泛型
标签: javascript typescript vue.js vue-composition-api