Skip to content

Commit 2dc9153

Browse files
sruenwgHarelM
andauthored
Improve expression types (#1128)
* improve array-related expression types * improve lookup expression types * improve interpolate expression types * improve types expression types * improve feature data expression types * improve decision expression types * improve math expression types * add tests for updated types * improve expression typings in docs * fix malformed "within" expression tests * use explicit typecheck tests in expression.test.ts * replace compileTimeCheck with Vitest typecheck * fix lint errors * unroll loops in expression unit tests * use `as` assertions for type narrowing --------- Co-authored-by: Harel M <[email protected]>
1 parent b59e484 commit 2dc9153

File tree

8 files changed

+1507
-250
lines changed

8 files changed

+1507
-250
lines changed

build/generate-style-spec.ts

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -157,18 +157,18 @@ export type CollatorExpressionSpecification =
157157
158158
export type InterpolationSpecification =
159159
| ['linear']
160-
| ['exponential', number | ExpressionSpecification]
161-
| ['cubic-bezier', number | ExpressionSpecification, number | ExpressionSpecification, number | ExpressionSpecification, number | ExpressionSpecification]
160+
| ['exponential', number]
161+
| ['cubic-bezier', number, number, number, number]
162162
163163
export type ExpressionSpecification =
164164
// types
165-
| ['array', unknown | ExpressionSpecification] // array
166-
| ['array', ExpressionInputType | ExpressionSpecification, unknown | ExpressionSpecification] // array
167-
| ['array', ExpressionInputType | ExpressionSpecification, number | ExpressionSpecification, unknown | ExpressionSpecification] // array
168-
| ['boolean', ...(unknown | ExpressionSpecification)[], unknown | ExpressionSpecification] // boolean
165+
| ['array', ExpressionSpecification] // array
166+
| ['array', 'string' | 'number' | 'boolean', ExpressionSpecification] // array
167+
| ['array', 'string' | 'number' | 'boolean', number, ExpressionSpecification] // array
168+
| ['boolean', unknown | ExpressionSpecification, ...(unknown | ExpressionSpecification)[]] // boolean
169169
| CollatorExpressionSpecification
170-
| ['format', ...(string | ['image', ExpressionSpecification] | ExpressionSpecification | {'font-scale'?: number | ExpressionSpecification, 'text-font'?: string[] | ExpressionSpecification, 'text-color'?: ColorSpecification | ExpressionSpecification})[]] // string
171-
| ['image', unknown | ExpressionSpecification] // image
170+
| ['format', ...(string | ['image', ExpressionSpecification] | ExpressionSpecification | {'font-scale'?: number | ExpressionSpecification, 'text-font'?: ExpressionSpecification, 'text-color'?: ColorSpecification | ExpressionSpecification, 'vertical-align'?: 'bottom' | 'center' | 'top'})[]] // string
171+
| ['image', string | ExpressionSpecification] // image
172172
| ['literal', unknown]
173173
| ['number', unknown | ExpressionSpecification, ...(unknown | ExpressionSpecification)[]] // number
174174
| ['number-format', number | ExpressionSpecification, {'locale'?: string | ExpressionSpecification, 'currency'?: string | ExpressionSpecification, 'min-fraction-digits'?: number | ExpressionSpecification, 'max-fraction-digits'?: number | ExpressionSpecification}] // string
@@ -178,47 +178,48 @@ export type ExpressionSpecification =
178178
| ['to-color', unknown | ExpressionSpecification, ...(unknown | ExpressionSpecification)[]] // color
179179
| ['to-number', unknown | ExpressionSpecification, ...(unknown | ExpressionSpecification)[]] // number
180180
| ['to-string', unknown | ExpressionSpecification] // string
181+
| ['typeof', unknown | ExpressionSpecification] // string
181182
// feature data
182183
| ['accumulated']
183-
| ['feature-state', string]
184+
| ['feature-state', string | ExpressionSpecification]
184185
| ['geometry-type'] // string
185186
| ['id']
186187
| ['line-progress'] // number
187188
| ['properties'] // object
188189
// lookup
189190
| ['at', number | ExpressionSpecification, ExpressionSpecification]
190-
| ['get', string | ExpressionSpecification, (Record<string, unknown> | ExpressionSpecification)?]
191-
| ['has', string | ExpressionSpecification, (Record<string, unknown> | ExpressionSpecification)?]
192-
| ['in', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification]
193-
| ['index-of', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification] // number
191+
| ['get', string | ExpressionSpecification, ExpressionSpecification?]
192+
| ['global-state', string]
193+
| ['has', string | ExpressionSpecification, ExpressionSpecification?]
194+
| ['in', null | ExpressionInputType | ExpressionSpecification, string | ExpressionSpecification]
195+
| ['index-of', null | ExpressionInputType | ExpressionSpecification, string | ExpressionSpecification, (number | ExpressionSpecification)?] // number
194196
| ['length', string | ExpressionSpecification]
195197
| ['slice', string | ExpressionSpecification, number | ExpressionSpecification, (number | ExpressionSpecification)?]
196198
// Decision
197199
| ['!', boolean | ExpressionSpecification] // boolean
198-
| ['!=', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
199-
| ['<', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
200-
| ['<=', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
201-
| ['==', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
202-
| ['>', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
203-
| ['>=', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
200+
| ['!=', null | ExpressionInputType | ExpressionSpecification, null | ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
201+
| ['<', string | number | ExpressionSpecification, string | number | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
202+
| ['<=', string | number | ExpressionSpecification, string | number | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
203+
| ['==', null | ExpressionInputType | ExpressionSpecification, null | ExpressionInputType | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
204+
| ['>', string | number | ExpressionSpecification, string | number | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
205+
| ['>=', string | number | ExpressionSpecification, string | number | ExpressionSpecification, CollatorExpressionSpecification?] // boolean
204206
| ['all', ...(boolean | ExpressionSpecification)[]] // boolean
205207
| ['any', ...(boolean | ExpressionSpecification)[]] // boolean
206-
| ['case', boolean | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
207-
...(boolean | ExpressionInputType | ExpressionSpecification)[], ExpressionInputType | ExpressionSpecification]
208+
| ['case', boolean | ExpressionSpecification, null | ExpressionInputType | ExpressionSpecification,
209+
...(boolean | null | ExpressionInputType | ExpressionSpecification)[], null | ExpressionInputType | ExpressionSpecification]
208210
| ['coalesce', ...(ExpressionInputType | ExpressionSpecification)[]] // at least two inputs required
209-
| ['match', ExpressionInputType | ExpressionSpecification,
210-
ExpressionInputType | ExpressionInputType[], ExpressionInputType | ExpressionSpecification,
211-
...(ExpressionInputType | ExpressionInputType[] | ExpressionSpecification)[], // repeated as above
212-
ExpressionInputType | ExpressionSpecification]
213-
| ['within', unknown | ExpressionSpecification]
214-
| ['distance', unknown | ExpressionSpecification]
211+
| ['match', string | number | ExpressionSpecification,
212+
string | number | string[] | number[], null | ExpressionInputType | ExpressionSpecification,
213+
...(string | number | string[] | number[] | null | ExpressionInputType | ExpressionSpecification)[], // repeated as above
214+
null | ExpressionInputType | ExpressionSpecification]
215+
| ['within', GeoJSON.GeoJSON]
215216
// Ramps, scales, curves
216217
| ['interpolate', InterpolationSpecification, number | ExpressionSpecification,
217-
...(number | number[] | ColorSpecification | ExpressionSpecification | ProjectionDefinitionSpecification )[]] // alternating number and number | number[] | ColorSpecification
218+
...(number | ColorSpecification | ExpressionSpecification | ProjectionDefinitionSpecification)[]] // alternating number and number | ColorSpecification | ExpressionSpecification | ProjectionDefinitionSpecification
218219
| ['interpolate-hcl', InterpolationSpecification, number | ExpressionSpecification,
219-
...(number | ColorSpecification)[]] // alternating number and ColorSpecificaton
220+
...(number | ColorSpecification | ExpressionSpecification)[]] // alternating number and ColorSpecificaton | ExpressionSpecification
220221
| ['interpolate-lab', InterpolationSpecification, number | ExpressionSpecification,
221-
...(number | ColorSpecification)[]] // alternating number and ColorSpecification
222+
...(number | ColorSpecification | ExpressionSpecification)[]] // alternating number and ColorSpecification | ExpressionSpecification
222223
| ['step', number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
223224
...(number | ExpressionInputType | ExpressionSpecification)[]] // alternating number and ExpressionInputType | ExpressionSpecification
224225
// Variable binding
@@ -247,8 +248,8 @@ export type ExpressionSpecification =
247248
| ['atan', number | ExpressionSpecification] // number
248249
| ['ceil', number | ExpressionSpecification] // number
249250
| ['cos', number | ExpressionSpecification] // number
250-
| ['distance', Record<string, unknown> | ExpressionSpecification] // number
251-
| ['ExpressionSpecification'] // number
251+
| ['distance', GeoJSON.GeoJSON] // number
252+
| ['e'] // number
252253
| ['floor', number | ExpressionSpecification] // number
253254
| ['ln', number | ExpressionSpecification] // number
254255
| ['ln2'] // number

0 commit comments

Comments
 (0)