如何在 Vue 组件数据上维护正确的打字稿类型?
How to maintain proper typescript type on Vue component data?
我正在开发一个 Vue 项目,我正在使用打字稿更新到 Vue 3。我发现打字稿 parser/compiler 有一个奇怪的行为。我有以下组件:
export default defineComponent({
name: 'Test',
data() {
return {
test: new Child(),
};
},
methods: {
testMethod: function () {
this.test = new Child();
let test2 = new Child();
}
},
});
class Child {
b = 0;
}
方法中,解析器认为test2
是Child
类型。但它认为 this.test
是 {b: number}
类型(即它已经失去了与 Child
的连接。将鼠标悬停在数据结构 (vscode) 上表明当它在那里创建时它认为类型是 Child
.
在这个例子中,这不是真正的问题,因为它可以很容易地施放它。但是如果 Child
被定义为:
class Parent {
private a = 1;
}
class Child extends Parent {
b = 0;
}
然后 this.test
仍然具有相同的类型 {b:number}
(它失去了私有成员)并且不能再转换为 Parent。这会导致无休止地类型转换为 any
以解决问题。它没有选择正确类型的另一个症状是 this.test.a = 3
生成 属性 不存在 (ts2339) 而 test2.a = 3;
生成 属性 是私有的,只能通过父级 (ts2341) 访问(这是正确的错误)。
我也尝试手动指定 return 类型的 data(),结果相同。
我做错了什么吗?这就是 Vue 插件与 Typescript 一起工作的方式吗?
如 here 所述,问题是 data
项是反应性的,而在 wrapping/unwrapping 中,class 丢失了。
那里的解决方案表明指示使用 shallowRef() (因为对于如此复杂的东西,通常首选保持实例原始):
export default defineComponent({
name: 'Test',
setup() {
return {
test: shallowRef(new Child()),
};
},
...
});
如果您不介意(或更喜欢)包装器,只需将 data
更改为 setup
即可解决输入问题:
export default defineComponent({
name: 'Test',
setup() {
return {
test: new Child(),
};
},
...
});
我正在开发一个 Vue 项目,我正在使用打字稿更新到 Vue 3。我发现打字稿 parser/compiler 有一个奇怪的行为。我有以下组件:
export default defineComponent({
name: 'Test',
data() {
return {
test: new Child(),
};
},
methods: {
testMethod: function () {
this.test = new Child();
let test2 = new Child();
}
},
});
class Child {
b = 0;
}
方法中,解析器认为test2
是Child
类型。但它认为 this.test
是 {b: number}
类型(即它已经失去了与 Child
的连接。将鼠标悬停在数据结构 (vscode) 上表明当它在那里创建时它认为类型是 Child
.
在这个例子中,这不是真正的问题,因为它可以很容易地施放它。但是如果 Child
被定义为:
class Parent {
private a = 1;
}
class Child extends Parent {
b = 0;
}
然后 this.test
仍然具有相同的类型 {b:number}
(它失去了私有成员)并且不能再转换为 Parent。这会导致无休止地类型转换为 any
以解决问题。它没有选择正确类型的另一个症状是 this.test.a = 3
生成 属性 不存在 (ts2339) 而 test2.a = 3;
生成 属性 是私有的,只能通过父级 (ts2341) 访问(这是正确的错误)。
我也尝试手动指定 return 类型的 data(),结果相同。
我做错了什么吗?这就是 Vue 插件与 Typescript 一起工作的方式吗?
如 here 所述,问题是 data
项是反应性的,而在 wrapping/unwrapping 中,class 丢失了。
那里的解决方案表明指示使用 shallowRef() (因为对于如此复杂的东西,通常首选保持实例原始):
export default defineComponent({
name: 'Test',
setup() {
return {
test: shallowRef(new Child()),
};
},
...
});
如果您不介意(或更喜欢)包装器,只需将 data
更改为 setup
即可解决输入问题:
export default defineComponent({
name: 'Test',
setup() {
return {
test: new Child(),
};
},
...
});