Skip to content

Commit b274faf

Browse files
committed
feat: better object property type infer (like glass-easel)
1 parent 5838186 commit b274faf

File tree

2 files changed

+45
-10
lines changed

2 files changed

+45
-10
lines changed

test/component.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ Component({
194194
type: Number,
195195
value: 1,
196196
},
197+
n3: {
198+
type: Number,
199+
value: 1 as const,
200+
},
197201
s: String,
198202
a: Array,
199203
a2: {
@@ -206,6 +210,12 @@ Component({
206210
type: Object,
207211
value: {} as Record<string, any>,
208212
},
213+
o3: {
214+
type: Object,
215+
value: {
216+
f1: 123,
217+
},
218+
},
209219
},
210220
methods: {
211221
g() {
@@ -216,12 +226,15 @@ Component({
216226
expectType<string>(this.g())
217227
expectType<number>(this.data.n)
218228
expectType<number>(this.data.n2)
229+
expectType<1>(this.data.n3)
219230
expectType<string>(this.data.s)
220231
expectType<any[]>(this.data.a)
221232
expectType<number[]>(this.data.a2)
222233
expectType<boolean>(this.data.b)
223234
expectType<Record<string, any>>(this.data.o)
224235
expectType<Record<string, any>>(this.data.o2)
236+
expectType<number>(this.data.o3.f1)
237+
expectError(this.data.o3.f2)
225238
expectType<any>(this.data.o2.city)
226239
expectType<any>(this.data.a[0])
227240
expectType<any>(this.data.o.prop)

types/wx/lib.wx.component.d.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ declare namespace WechatMiniprogram.Component {
144144
/** 组件的方法,包括事件响应函数和任意的自定义方法,关于事件响应函数的使用,参见 [组件间通信与事件](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html) */
145145
methods: M & (TIsPage extends true ? Partial<Page.ILifetime> : {})
146146
}
147+
148+
type Satisfy<T, V> = V extends T ? V : T
147149
type PropertyType =
148150
| StringConstructor
149151
| NumberConstructor
@@ -164,11 +166,24 @@ declare namespace WechatMiniprogram.Component {
164166
: T extends ObjectConstructor
165167
? IAnyObject
166168
: never
167-
type FullProperty<T extends PropertyType> = {
169+
type SimpleValueType<T extends PropertyType, V> = T extends StringConstructor
170+
? Satisfy<string, V>
171+
: T extends NumberConstructor
172+
? Satisfy<number, V>
173+
: T extends BooleanConstructor
174+
? Satisfy<boolean, V>
175+
: T extends ArrayConstructor
176+
? Satisfy<any[], V>
177+
: T extends ObjectConstructor
178+
? Satisfy<Record<string, any> | null, V>
179+
: T extends FunctionConstructor
180+
? Satisfy<(...args: any[]) => any, V>
181+
: never
182+
type FullProperty<T extends PropertyType, V extends ValueType<T>> = {
168183
/** 属性类型 */
169184
type: T
170185
/** 属性初始值 */
171-
value?: ValueType<T>
186+
value?: V
172187
/** 属性值被更改时的响应函数 */
173188
observer?:
174189
| string
@@ -181,12 +196,12 @@ declare namespace WechatMiniprogram.Component {
181196
optionalTypes?: ShortProperty[]
182197
}
183198
type AllFullProperty =
184-
| FullProperty<StringConstructor>
185-
| FullProperty<NumberConstructor>
186-
| FullProperty<BooleanConstructor>
187-
| FullProperty<ArrayConstructor>
188-
| FullProperty<ObjectConstructor>
189-
| FullProperty<null>
199+
| FullProperty<StringConstructor, any>
200+
| FullProperty<NumberConstructor, any>
201+
| FullProperty<BooleanConstructor, any>
202+
| FullProperty<ArrayConstructor, any>
203+
| FullProperty<ObjectConstructor, any>
204+
| FullProperty<null, any>
190205
type ShortProperty =
191206
| StringConstructor
192207
| NumberConstructor
@@ -198,8 +213,15 @@ declare namespace WechatMiniprogram.Component {
198213
type PropertyToData<T extends AllProperty> = T extends ShortProperty
199214
? ValueType<T>
200215
: FullPropertyToData<Exclude<T, ShortProperty>>
201-
type ArrayOrObject = ArrayConstructor | ObjectConstructor
202-
type FullPropertyToData<T extends AllFullProperty> = T['type'] extends ArrayOrObject ? unknown extends T['value'] ? ValueType<T['type']> : T['value'] : ValueType<T['type']>
216+
type FullPropertyToData<T> = T extends FullProperty<infer T, infer V>
217+
? unknown extends V
218+
? ValueType<T>
219+
: ((a: T) => void) extends (a: PropertyType) => void
220+
? V
221+
: V extends ValueType<T>
222+
? SimpleValueType<T, V>
223+
: never
224+
: never
203225
type PropertyOptionToData<P extends PropertyOption> = {
204226
[name in keyof P]: PropertyToData<P[name]>
205227
}

0 commit comments

Comments
 (0)