From f604100e193523ce45ee79429a73144742dfc2f3 Mon Sep 17 00:00:00 2001 From: Jiayu Liu Date: Tue, 28 Aug 2018 10:03:26 +0800 Subject: [PATCH] weixin-app add call-site typecheck value types for data/properties --- types/weixin-app/index.d.ts | 35 +++++++++++++++++++++------- types/weixin-app/weixin-app-tests.ts | 34 ++++++++++++++++----------- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/types/weixin-app/index.d.ts b/types/weixin-app/index.d.ts index ed76a02b21..ecdbd1e486 100644 --- a/types/weixin-app/index.d.ts +++ b/types/weixin-app/index.d.ts @@ -4,7 +4,7 @@ // AlexStacker // Jimexist // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.3 +// TypeScript Version: 2.8 declare namespace wx { // #region 基本参数 @@ -3369,17 +3369,17 @@ type ThisTypedComponentOptionsWithRecordProps< ComponentOptions Data), Methods, Options, Props> & ThisType>>; -interface ComponentRelation { +interface ComponentRelation { /** 目标组件的相对关系,可选的值为 parent 、 child 、 ancestor 、 descendant */ type: "parent" | "child" | "ancestor" | "descendant"; /** 如果这一项被设置,则它表示关联的目标节点所应具有的behavior,所有拥有这一behavior的组件节点都会被关联 */ target?: string; /** 关系生命周期函数,当关系被建立在页面节点树中时触发,触发时机在组件attached生命周期之后 */ - linked?: (target: Component) => void; + linked?: (target: Component) => void; /** 关系生命周期函数,当关系在页面节点树中发生改变时触发,触发时机在组件moved生命周期之后 */ - linkChanged?: (target: Component) => void; + linkChanged?: (target: Component) => void; /** 关系生命周期函数,当关系脱离页面节点树时触发,触发时机在组件detached生命周期之后 */ - unlinked?: (target: Component) => void; + unlinked?: (target: Component) => void; } /** * Component组件参数 @@ -3447,6 +3447,25 @@ interface ComponentOptions< */ relations?: { [key: string]: ComponentRelation }; } + +/** + * There are two valid ways to define the type of data / properties: + * + * 1. { name: valueType } + * 2. { name: { type: valueType, value?: value } } + * + * and this conditional type will extract that out so the call-site will typecheck. + * + * Note this is different from PropOptions as it is the definitions you passed to Component function + * whereas this type is for call-site. + */ +type DataValueType = Def extends { + type: (...args: any[]) => infer T; + value?: infer T; +} + ? T + : Def extends (...args: any[]) => infer T ? T : never; + /** * Component实例方法 */ @@ -3466,12 +3485,12 @@ interface Component { /** * 组件数据,包括内部数据和属性值 */ - data: D & P; + data: { [key in keyof (D & P)]: DataValueType<(D & P)[key]> }; /** * 组件数据,包括内部数据和属性值(与 data 一致) */ - properties: D & P; + properties: { [key in keyof (D & P)]: DataValueType<(D & P)[key]> }; /** * 将数据从逻辑层发送到视图层,同时改变对应的 this.data 的值 * 1. 直接修改 this.data 而不调用 this.setData 是无法改变页面的状态的,还会造成数据不一致。 @@ -3491,7 +3510,7 @@ interface Component { | null | any[] }, - callback?: () => any + callback?: () => void ): void; /** * 检查组件是否具有 behavior diff --git a/types/weixin-app/weixin-app-tests.ts b/types/weixin-app/weixin-app-tests.ts index 1532274ca4..473e8a290d 100644 --- a/types/weixin-app/weixin-app-tests.ts +++ b/types/weixin-app/weixin-app-tests.ts @@ -16,13 +16,11 @@ let behavior = Behavior({ } }, data: { - myBehaviorData: {} + myBehaviorData: "" }, attached() {}, methods: { - myBehaviorMethod() { - this.properties.myBehaviorData; - } + myBehaviorMethod() {} } }); @@ -50,20 +48,28 @@ Component({ // 生命周期函数,可以为函数,或一个在methods段中定义的方法名 attached() { - this.setData({}, () => {}); + this.setData( + { + key: "123" + }, + () => {} + ); }, moved() {}, detached() {}, methods: { readMyDataAndMyProps() { - this.data.myProperty; - this.data.myProperty2; - this.data.key; + const stringValue1: string = this.data.myProperty; + const stringValue2: string = this.data.myProperty2; + const stringValue3: string = this.data.key; this.data.anotherKey; this.properties.myProperty; this.properties.myProperty2; this.properties.key; this.properties.anotherKey; + this.setData({ + key: stringValue1 + stringValue2 + stringValue3 + }); }, onMyButtonTap() { // 更新属性和数据的方法与更新页面数据的方法类似 @@ -86,17 +92,17 @@ Component({ relations: { "./custom-ul": { type: "parent", // 关联的目标节点应为父节点 - linked(target) { + linked(target: Component<{ key: string }, {}>) { // 每次被插入到custom-ul时执行,target是custom-ul节点实例对象,触发在attached生命周期之后 - target.data; + target.data.key; }, - linkChanged(target) { + linkChanged(target: Component<{ key: string }, {}>) { // 每次被移动后执行,target是custom-ul节点实例对象,触发在moved生命周期之后 - target.data; + target.data.key; }, - unlinked(target) { + unlinked(target: Component<{ key: string }, {}>) { // 每次被移除时执行,target是custom-ul节点实例对象,触发在detached生命周期之后 - target.data; + target.data.key; } } }