笔者并不标题党,如果你要用更标准的TS
的开发小程序,你一定会遇到这个问题,可能让你在小程序TS化的道理上戛然而止。
先看下社区的问题,点击查看
Update(2019-09-24)
这个问题如果在小程序SDK 2.7.2
已经修复了,如果你的受众是基础库大于2.7.2
,请忽略这篇文章
简单来说问题是怎么样的
class Parent {}
class Child extends Parent {
}
Page(new Child())
运行上面这段代码,在SDK 2.7.2
以下的版本会报如下错误。
// error 1
Uncaught TypeError: Cannot assign to read only property 'constructor' of object '#<V>'
at G (VM63 WAService.js:1)
at Object.t (VM63 WAService.js:1)
at mt (VM63 WAService.js:1)
at Rt (VM63 WAService.js:1)
at index.ts:8
at require (VM63 WAService.js:1)
at <anonymous>:11:7
at HTMLScriptElement.scriptLoaded (appservice?t=1569326156124:1147)
at HTMLScriptElement.script.onload (appservice?t=1569326156124:1159)
// error 2
Page is not constructed because it is not found.
解决上面问题的方案三个方向
- 这种情况发送在派生类里如果没有
class Child extends Parent
,也不会报这个错,单这不符合预期,限制了开发者使用 - 在删除同文件夹的
index.json
的usingComponents: {}
, 单这不符合实际开发,实际开发项目肯定要引用组件 - 聚焦错误本身,看下面源码
var r = qsa.registerElement(e)
, o = Object.create(q, { // 打断点后发现这个 o 就是那个Parent
constructor: {
value: V
}
});
qsa.Behavior.prepare(r.behavior);
var a = r.behavior.methods; // 打断点后 a 就是那个Child
for (var i in a)
o[i] = a[i]; // 在这行报错 说Cannot assign to read only property 'constructor' of object '#<V>'
return o
不能a
的constructor
属性赋值给o
的只读属性constructor
;
那么解决方案就是
class Parent {}
class Child extends Parent {
}
const options = new Child();
// @ts-ignore
delete options.__proto__.constuctor
Page(new Child())
这样写能解决问题,但不够优雅。那么优雅的解决方案是
class Parent {
constructor() {
// @ts-ignore
delete this.__proto__.constructor
}
}
class Child extends Parent {
// 这里可以不用写 默认也是要调用的
// 这里显式调用 主要是为了让读者更容易了解
constructor() {
super()
}
}
Page(new Child())
EDN
这样就完美解决了该问题。同时也给大家提供了一种解决问题的思路
- 先找出问题的最小代码
- 一步一步debug源码,即使压缩了也不要怕
- 用最优雅的方式解决问题