api-typings
api-typings copied to clipboard
Component中的FullPropertyToData的定义有问题?
lib.wx.component.d.ts 中
type PropertyToData<T extends AllProperty> = T extends ShortProperty
? ValueType<T>
: FullPropertyToData<Exclude<T, ShortProperty>>
type FullPropertyToData<T extends AllFullProperty> = ValueType<T['type']>
当 FullProperty 中 type 为 Object 时,ValueType<T['type']> 总是为 IAnyObject 的,并无法得到推断后具体的类型。 考虑一个例子:
Component({
properties: {
person: {
type: Object,
value: {
age: 0,
name: '',
}
}
},
attached() {
this.data.person.age = '1' // 这里预期应当是报错的。但由于 person 被识别为 IAnyObject,被判为通过了
}
})
但是如果修改成如下的定义后,上面的例子就符合预期了
type FullPropertyToData<T extends AllFullProperty> = unknown extends T['value'] ? ValueType<T['type']> : T['value']
Component({
properties: {
person: {
type: Object,
value: {
age: 0,
name: '',
}
}
},
attached() {
this.data.age = '1' // 符合预期。这里会报错,Type 'string' is not assignable to type 'number'.
}
})
猜想 T['value'] 是推断后的类型,因此能拿到具体的字段类型信息。
这样修改后,应当可以满足 https://github.com/wechat-miniprogram/api-typings/issues/188 的需求
确实有效,改了之后会把 type: Object
的情况从 Record<string, any>
限制到具体类型,跑了一下有用例会挂,是个 breaking change,得稍微慎重一点
还有个小问题是 bool: { type: Boolean, value: true }
会推导出 this.data.b: true
,应该是有些太严格了,不过字面量的几个类型可以通过 T['type']
来特殊处理掉
因为最近在做框架,所以自己按照vue的格式实现了一套接口,用自己包装的注册器转换。
而且我之前也有说过想提pr来着。
小程序这里对比vue就是个大坑。
一个是没有required,理论上没有value的都应该推导出undefined,但实际上没有 第二个就是optionalTypes,导致如果做实际的类型推导必须额外加一个泛型,还要取union,导致类型infer很难做 第三个就是自带的observer,因为需要从 types 和 optionalTypes 同时推断,导致类似vue的as PropType没法work,会存在循环引用或者判断的情况
所以我最终也没找到一个很好的写法。。。
确实有效,改了之后会把
type: Object
的情况从Record<string, any>
限制到具体类型,跑了一下有用例会挂,是个 breaking change,得稍微慎重一点还有个小问题是
bool: { type: Boolean, value: true }
会推导出this.data.b: true
,应该是有些太严格了,不过字面量的几个类型可以通过T['type']
来特殊处理掉
true 这个问题,是TS专门针对这个类型进行了处理,会将true/false推断成常量类型,而不是boolean,其它情况应该是OK的,所以可以稍作修改来绕过去
type FullPropertyToData<T extends AllFullProperty> = unknown extends T['value'] ? ValueType<T['type']>
: T['value'] extends true | false
? boolean
: T['value']
确实有效,改了之后会把
type: Object
的情况从Record<string, any>
限制到具体类型,跑了一下有用例会挂,是个 breaking change,得稍微慎重一点
看了一下 breaking changes:
test/component.test.ts:181:6 ✖ 181:6 Parameter type any[] is not identical to argument type number[]. ✖ 221:6 Parameter type any[] is not identical to argument type number[]. ✖ 246:6 Parameter type any[] is not identical to argument type number[].
test/issue.test.ts:407:8 ✖ 407:8 Parameter type Record<string, any> is declared too wide for argument type { skuNum: number; }.
component.test.ts 中的 3 个应该是正常的,测试用例需要做相应的修改。 issue.test.ts 可以再确认一下,我判断也是需要修改测试用例。
这些用例都是在假定拿到的是 any 来判断的,与添加这个功能后的结果实际不相符
那改还是不改。 反正怎么改,如果properties值为Object,我定义了接口,类型都推断不出来
因为最近在做框架,所以自己按照vue的格式实现了一套接口,用自己包装的注册器转换。
而且我之前也有说过想提pr来着。
小程序这里对比vue就是个大坑。
一个是没有required,理论上没有value的都应该推导出undefined,但实际上没有 第二个就是optionalTypes,导致如果做实际的类型推导必须额外加一个泛型,还要取union,导致类型infer很难做 第三个就是自带的observer,因为需要从 types 和 optionalTypes 同时推断,导致类似vue的as PropType没法work,会存在循环引用或者判断的情况
所以我最终也没找到一个很好的写法。。。
这个 observer 感觉有点坑,没办法让泛型作用在我们输入的 options 上