Skip to content

Commit 075821a

Browse files
Fix/improve expression type (#1510)
* Fix interpolate typings: allow number arrays, but no expressions. Fix step typing. Simplify +, concat, coalesce typings. * additional tests for "step"
1 parent 0c76546 commit 075821a

2 files changed

Lines changed: 43 additions & 17 deletions

File tree

build/generate-style-spec.ts

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -187,30 +187,26 @@ export type ExpressionSpecification =
187187
| ['any', ...(boolean | ExpressionSpecification)[]] // boolean
188188
| ['case', boolean | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
189189
...(boolean | ExpressionInputType | ExpressionSpecification)[], ExpressionInputType | ExpressionSpecification]
190-
| ['coalesce', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
191-
...(ExpressionInputType | ExpressionSpecification)[]]
190+
| ['coalesce', ...(ExpressionInputType | ExpressionSpecification)[]] // at least two inputs required
192191
| ['match', ExpressionInputType | ExpressionSpecification,
193192
ExpressionInputType | ExpressionInputType[], ExpressionInputType | ExpressionSpecification,
194193
...(ExpressionInputType | ExpressionInputType[] | ExpressionSpecification)[], // repeated as above
195194
ExpressionInputType]
196195
| ['within', unknown | ExpressionSpecification]
197196
// Ramps, scales, curves
198-
| ['interpolate', InterpolationSpecification,
199-
number | ExpressionSpecification, ...(number | ExpressionInputType | ExpressionSpecification)[]]
200-
| ['interpolate-hcl', InterpolationSpecification,
201-
number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
202-
...(number | ColorSpecification | ExpressionSpecification)[]]
203-
| ['interpolate-lab', InterpolationSpecification,
204-
number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
205-
...(number | ColorSpecification | ExpressionSpecification)[]]
206-
| ['step', number | ExpressionSpecification, number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
207-
...(number | ExpressionInputType | ExpressionSpecification)[]]
197+
| ['interpolate', InterpolationSpecification, number | ExpressionSpecification,
198+
...(number | number[] | ColorSpecification)[]] // alternating number and number | number[] | ColorSpecification
199+
| ['interpolate-hcl', InterpolationSpecification, number | ExpressionSpecification,
200+
...(number | ColorSpecification)[]] // alternating number and ColorSpecificaton
201+
| ['interpolate-lab', InterpolationSpecification, number | ExpressionSpecification,
202+
...(number | ColorSpecification)[]] // alternating number and ColorSpecification
203+
| ['step', number | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
204+
...(number | ExpressionInputType | ExpressionSpecification)[]] // alternating number and ExpressionInputType | ExpressionSpecification
208205
// Variable binding
209206
| ['let', string, ExpressionInputType | ExpressionSpecification, ...(string | ExpressionInputType | ExpressionSpecification)[]]
210207
| ['var', string]
211208
// String
212-
| ['concat', ExpressionInputType | ExpressionSpecification, ExpressionInputType | ExpressionSpecification,
213-
...(ExpressionInputType | ExpressionSpecification)[]] // string
209+
| ['concat', ...(ExpressionInputType | ExpressionSpecification)[]] // at least two inputs required -> string
214210
| ['downcase', string | ExpressionSpecification] // string
215211
| ['is-supported-script', string | ExpressionSpecification] // boolean
216212
| ['resolved-locale', CollatorExpressionSpecification] // string
@@ -225,7 +221,7 @@ export type ExpressionSpecification =
225221
| ['/', number | ExpressionSpecification, number | ExpressionSpecification] // number
226222
| ['%', number | ExpressionSpecification, number | ExpressionSpecification] // number
227223
| ['^', number | ExpressionSpecification, number | ExpressionSpecification] // number
228-
| ['+', number | ExpressionSpecification, number | ExpressionSpecification, ...(number | ExpressionSpecification)[]] // number
224+
| ['+', ...(number | ExpressionSpecification)[]] // at least two inputs required -> number
229225
| ['abs', number | ExpressionSpecification] // number
230226
| ['acos', number | ExpressionSpecification] // number
231227
| ['asin', number | ExpressionSpecification] // number

src/style-spec/feature_filter/feature_filter.test.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ import Point from '@mapbox/point-geometry';
55
import MercatorCoordinate from '../../geo/mercator_coordinate';
66
import EXTENT from '../../data/extent';
77
import {CanonicalTileID} from '../../source/tile_id';
8-
import {ExpressionFilterSpecification, FilterSpecification} from '../types.g';
8+
import {ExpressionFilterSpecification, ExpressionInputType, ExpressionSpecification, FilterSpecification} from '../types.g';
99
import {Feature} from '../expression';
1010

1111
describe('filter', () => {
12-
test('exprssions transpilation test', () => {
12+
test('expressions transpilation test', () => {
1313
function compileTimeCheck(_: ExpressionFilterSpecification) {
1414
expect(true).toBeTruthy();
1515
}
@@ -36,13 +36,43 @@ describe('filter', () => {
3636
compileTimeCheck(['match', ['get', 'TYPE'], ['TARGETPOINT:HOSPITAL'], true, false]);
3737
compileTimeCheck(['match', ['get', 'TYPE'], ['ADIZ', 'AMA', 'AWY', 'CLASS', 'NO-FIR', 'OCA', 'OTA', 'P', 'RAS', 'RCA', 'UTA', 'UTA-P'], true, false]);
3838
compileTimeCheck(['==', ['get', 'MILITARYAIRPORT'], 1]);
39+
compileTimeCheck(['interpolate', ['linear'], ['line-progress'], 0, 10, 0.5, 100, 1, 1000]); // number output
40+
compileTimeCheck(['interpolate', ['linear'], ['line-progress'], 0, 'red', 0.5, 'green', 1, 'blue']); // color output
41+
compileTimeCheck(['interpolate', ['linear'], ['line-progress'], 0, [10, 20, 30], 0.5, [20, 30, 40], 1, [30, 40, 80]]); // number array output!
42+
compileTimeCheck(['interpolate-hcl', ['linear'], ['line-progress'], 0, 'red', 0.5, 'green', 1, 'blue']);
43+
compileTimeCheck(['interpolate-lab', ['linear'], ['line-progress'], 0, 'red', 0.5, 'green', 1, 'blue']);
44+
compileTimeCheck(['step', ['get', 'point_count'], '#df2d43', 50, '#df2d43', 200, '#df2d43']);
45+
compileTimeCheck(['step', ['get', 'point_count'], 20, 50, 30, 200, 40]);
46+
compileTimeCheck(['step', ['get', 'point_count'], 0.6, 50, 0.7, 200, 0.8]);
47+
48+
// checks, where parts of the expression are injected from constants
49+
// as in most cases the styling is read from JSON, these are rather optional tests.
50+
// due to typescript inferring rather broad types, this is only possible in few places without specifying a type for the constant.
3951
const colorStops = [0, 'red', 0.5, 'green', 1, 'blue'];
4052
compileTimeCheck([
4153
'interpolate',
4254
['linear'],
4355
['line-progress'],
4456
...colorStops
4557
]);
58+
compileTimeCheck([
59+
'interpolate-hcl',
60+
['linear'],
61+
['line-progress'],
62+
...colorStops
63+
]);
64+
compileTimeCheck([
65+
'interpolate-lab',
66+
['linear'],
67+
['line-progress'],
68+
...colorStops
69+
]);
70+
const [firstOutput, ...steps] = ['#df2d43', 50, '#df2d43', 200, '#df2d43'];
71+
compileTimeCheck(['step', ['get', 'point_count'], firstOutput, ...steps]);
72+
const strings = ['first', 'second', 'third'];
73+
compileTimeCheck(['concat', ...strings]);
74+
const values: (ExpressionInputType | ExpressionSpecification)[] = [['get', 'name'], ['get', 'code'], 'NONE']; // type is necessary!
75+
compileTimeCheck(['coalesce', ...values]);
4676
});
4777

4878
test('expression, zoom', () => {

0 commit comments

Comments
 (0)