@sheetxl/primitives 0.7.28-beta.4 → 0.8.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
1
  import { Scalar } from './Scalar';
2
2
  import { ScalarType } from './ScalarType';
3
+ import { ValueKind } from './ValueKind';
3
4
  /**
4
5
  * A self-describing, type-safe, executable function.
5
6
  *
@@ -35,6 +36,16 @@ export interface IFunction {
35
36
  * Indicates whether the function is a built-in function.
36
37
  */
37
38
  isBuiltIn(): boolean;
39
+ /**
40
+ * Indicates whether the function is a defined name whose body is `LAMBDA(…)`.
41
+ *
42
+ * @remarks
43
+ * A named lambda is reachable by name like any other function, so signature help and function
44
+ * lookups can describe it: its parameters are the lambda's, and its summary is the name's
45
+ * comment, or the name's formula when it has no comment. A formula calls it through the NAME,
46
+ * never through {@link execute}, which answers `#CALC!`.
47
+ */
48
+ isLambda(): boolean;
38
49
  /**
39
50
  * Returns the execution environment this function belongs to.
40
51
  *
@@ -125,17 +136,47 @@ export declare namespace IFunction {
125
136
  */
126
137
  getName(): string;
127
138
  /**
128
- * The DECLARED error policy, or `null` when the parameter relies on the default.
139
+ * True when a BARE error at this parameter — an error instead of a value or a range, `NA()`,
140
+ * `#NAME?`, a union where one rectangle is needed — is delivered to the body RAW rather than
141
+ * propagated: the `AcceptError<T>` marker. A rule, not a type — the engine's auto-reject is
142
+ * off at this slot, and the body narrows with `FormulaError.isError` if it cares.
129
143
  *
130
144
  * @remarks
131
- * `null` is the common case and it is not "no policy": the default is REJECT in every position
132
- * — scalar, lifted, flattened and range alike — so `null` means reject. There is deliberately
133
- * no `'reject'` value to declare it with; a `RejectError<T>` marker existed, said exactly what
134
- * `null` already says, and was removed rather than left as a second spelling.
145
+ * The default, and the common case, is that the error propagates with its identity and the
146
+ * body never runs. The marker never looks INSIDE a container: an error member of a range
147
+ * reaches the body either way and is the body's to judge (`IRange.firstError`).
148
+ *
149
+ * @see {@link ParameterTypeJSON.acceptError}
150
+ */
151
+ isAcceptError(): boolean;
152
+ /**
153
+ * True when a multi-cell REFERENCE at this scalar parameter is `#VALUE!` rather than a
154
+ * broadcast — the `NoLift<T>` marker.
155
+ *
156
+ * @see {@link ParameterTypeJSON.noLift}
157
+ */
158
+ isNoLift(): boolean;
159
+ /**
160
+ * True when the members reaching this repeating scalar parameter are coerced rather than
161
+ * filtered — the `NoFilter<T>` marker.
162
+ *
163
+ * @see {@link ParameterTypeJSON.noFilter}
164
+ */
165
+ isNoFilter(): boolean;
166
+ /**
167
+ * True when the argument at this parameter may reach the body UNEVALUATED, as an `ILazy`
168
+ * handle — the `Lazy<T>` marker.
169
+ *
170
+ * @see {@link ParameterTypeJSON.lazy}
171
+ */
172
+ isLazy(): boolean;
173
+ /**
174
+ * True when the parameter takes EITHER a value or a range, decided per argument by its kind —
175
+ * an `IRange | Scalar` union.
135
176
  *
136
- * @see {@link ParameterTypeJSON.errors}
177
+ * @see {@link ParameterTypeJSON.valueOrRange}
137
178
  */
138
- getErrorPolicy(): 'accept' | 'accept-ref' | null;
179
+ isValueOrRange(): boolean;
139
180
  /**
140
181
  * Indicates whether the parameter is required.
141
182
  */
@@ -181,11 +222,60 @@ export declare namespace IFunction {
181
222
  */
182
223
  isRest(): boolean;
183
224
  /**
184
- * Indicates that the parameter is limited to a list of specific values.
185
- * If the input value is a `string` it will be passed as a case-insensitive version.
186
- * If the input value is a `number` it will be passed as a value against the offset.
225
+ * The enum the parameter is limited to, or `null` when it takes any value of its type.
226
+ *
227
+ * @remarks
228
+ * Declared by typing the parameter as a TypeScript `enum`, as an alias paired with a same-name
229
+ * `as const` object, or as a union of number or string literals (`0 | 1`).
230
+ *
231
+ * @see {@link IEnum}
232
+ */
233
+ getEnum(): IFunction.IEnum | null;
234
+ }
235
+ /**
236
+ * One member of an {@link IEnum}.
237
+ */
238
+ interface IEnumMember {
239
+ /**
240
+ * The declared member name (`End`). For a union of bare literals, which names nothing, this is
241
+ * the value as text.
187
242
  */
188
- getEnums(): readonly string[];
243
+ getName(): string;
244
+ /**
245
+ * The value a formula passes. Typed, and never localized.
246
+ */
247
+ getValue(): number | string;
248
+ /**
249
+ * Whether the member is declared but not offered, from the member's `@deprecated` tag.
250
+ *
251
+ * @remarks
252
+ * A deprecated member stays in the set, so a formula that passes it is not refused and the
253
+ * function decides what it answers. It is left out of the argument dropdown and the values
254
+ * a warning lists. A string is the tag's label (`Excel desktop only`).
255
+ */
256
+ isDeprecated(): boolean | string;
257
+ }
258
+ /**
259
+ * A closed set of values a parameter accepts.
260
+ *
261
+ * @remarks
262
+ * All members are numbers or all are strings; the two never mix. The set is free-form: it does
263
+ * not have to be contiguous or start at zero (`-1 | 0 | 1`).
264
+ */
265
+ interface IEnum {
266
+ /**
267
+ * The declared type name (`PaymentType`), unique within the module that declares it. For a
268
+ * union of bare literals it is the values joined by `|`.
269
+ */
270
+ getId(): string;
271
+ /**
272
+ * Whether the members are numbers or strings.
273
+ */
274
+ getScalarType(): typeof ScalarType.Number | typeof ScalarType.String;
275
+ /**
276
+ * The members, in declaration order.
277
+ */
278
+ getMembers(): readonly IFunction.IEnumMember[];
189
279
  }
190
280
  /**
191
281
  * Describes the runtime return behavior of a function, including modifiers like
@@ -196,6 +286,14 @@ export declare namespace IFunction {
196
286
  * If none are specified, The value will be returned with no special behavior.
197
287
  */
198
288
  interface IReturnType extends IValueType {
289
+ /**
290
+ * The declared {@link ValueKind} of the result — the declared override where one exists, else
291
+ * the kind the type spellings imply — or `null` when the result's kind follows the value
292
+ * itself (`'*'`, an untyped return).
293
+ *
294
+ * @see {@link ReturnTypeJSON.kind}
295
+ */
296
+ getKind(): ValueKind | null;
199
297
  /**
200
298
  * Indicates the return value is a Promise or Promise-like (i.e., async).
201
299
  * The system will mark the result as pending and re-trigger evaluation once resolved.
@@ -209,6 +307,17 @@ export declare namespace IFunction {
209
307
  * @defaultValue `false`
210
308
  */
211
309
  isStreaming(): boolean;
310
+ /**
311
+ * True when the result can change with nothing dirty, so a cell naming this function
312
+ * recalculates on every pass — the `Volatile<T>` marker.
313
+ *
314
+ * @remarks
315
+ * STATIC, and read from the formula text at compile time: it is true of the call whether or
316
+ * not the call runs, which is what a lazy argument (and Excel) requires.
317
+ *
318
+ * @see {@link ReturnTypeJSON.volatile}
319
+ */
320
+ isVolatile(): boolean;
212
321
  }
213
322
  /**
214
323
  * The type-system metadata the engine reads to coerce arguments, apply broadcasting,
@@ -237,6 +346,17 @@ export declare namespace IFunction {
237
346
  * If not specified, the function is assumed to be volatile (its output might change even if its inputs haven't).
238
347
  */
239
348
  getParameters(): readonly IParameterType[];
349
+ /**
350
+ * The largest number of arguments a call to this function may carry.
351
+ *
352
+ * @remarks
353
+ * Only meaningful for a VARIADIC function; a fixed parameter list is already its own maximum.
354
+ * The number is the whole CALL's argument count, prefix and optional suffix included, and it
355
+ * is refused where Excel refuses it — at entry, before evaluation.
356
+ *
357
+ * @see {@link Repeating}
358
+ */
359
+ getMaxArguments(): number;
240
360
  /**
241
361
  * Metadata describing the type and dimensionality of the return value.
242
362
  *
@@ -252,7 +372,11 @@ export declare namespace IFunction {
252
372
  */
253
373
  interface IDescriptor {
254
374
  /**
255
- * A overwritten name for the function.
375
+ * The canonical name of the function, matching {@link IDeclaration.getName}.
376
+ *
377
+ * @remarks
378
+ * A descriptor may override the name; when it does not, this is the name of the function
379
+ * in code. Use {@link getNameLocal} for display.
256
380
  */
257
381
  getName(): string;
258
382
  /**
@@ -297,6 +421,31 @@ export declare namespace IFunction {
297
421
  example?: string;
298
422
  defaultValue?: Scalar;
299
423
  }>>;
424
+ /**
425
+ * Describe each enum the function's parameters are limited to.
426
+ *
427
+ * @remarks
428
+ * The keys are enum ids (see {@link IEnum.getId}), and within one the member names (see
429
+ * {@link IEnumMember.getName}). Every enum a parameter declares has an entry and every member
430
+ * has one within it, so a caller can read a label without checking: `nameLocal` falls back to
431
+ * the declared name. Values are never localized — they are on the declaration.
432
+ */
433
+ getEnums(): Readonly<Record<string, IFunction.IEnumDescription>>;
434
+ }
435
+ /**
436
+ * The copy for one enum: what it is, and what each member means.
437
+ */
438
+ interface IEnumDescription {
439
+ /** The enum's name in the user's language, or its declared name. */
440
+ readonly nameLocal: string;
441
+ /** What the enum controls. */
442
+ readonly summary?: string;
443
+ /** By member name. */
444
+ readonly members: Readonly<Record<string, {
445
+ /** The member's name in the user's language, or its declared name. */
446
+ readonly nameLocal: string;
447
+ readonly description?: string;
448
+ }>>;
300
449
  }
301
450
  /**
302
451
  * Describes the type characteristics of a function parameter or return value.
@@ -394,7 +543,8 @@ export declare namespace IFunction {
394
543
  * @remarks
395
544
  * Descriptive rather than applied: an absent argument is never pushed, so the initializer
396
545
  * supplies the value itself. It is recorded so help text, tooltips and completions can say
397
- * "defaults to 3" without reading the source.
546
+ * "defaults to 3" without reading the source. The exception is a {@link lazy} slot, which has
547
+ * no initializer to run — `Lazy<T, V>` declares the default here and the engine applies it.
398
548
  *
399
549
  * Present for a literal initializer only. One computed from another argument
400
550
  * (`numberS2: number = numberS`) has no value to record and leaves this undefined.
@@ -454,28 +604,126 @@ export declare namespace IFunction {
454
604
  */
455
605
  repeating?: ParameterTypeJSON[];
456
606
  /**
457
- * The DECLARED error policy, generated from the `AcceptError<T>` / `AcceptRefError<T>`
458
- * parameter markers.
607
+ * A BARE error at this parameter — an error instead of a value or a range — is delivered to
608
+ * the body RAW rather than propagated: the engine's auto-reject is off at this slot, and the
609
+ * body narrows if it cares. Generated from the `AcceptError<T>` marker. A failed COERCION to
610
+ * the declared type is delivered the same way, as the `#VALUE!` it would have raised, so a
611
+ * body that rethrows what it receives answers exactly as the engine would have — and one that
612
+ * reads its arguments in its own order can (`IFS(TRUE,1,"x",2)` is 1: the pair is never
613
+ * reached).
614
+ *
615
+ * @remarks
616
+ * OMITTED is the default (ErrorPolicy.ts): the error propagates with its identity (a scalar
617
+ * argument), becomes an error member of the output (a lifted member), or short-circuits on the
618
+ * first error in argument order (a flattened list) — the body never runs. A
619
+ * `FormulaError.Known`-typed parameter receives without the marker, because the type declares
620
+ * it. On a TYPED range (`IRange<number>`) the marker also lets error members ride through the
621
+ * typed read raw — COUNT's profile. Errors INSIDE a range are otherwise never the marker's
622
+ * business: a valid range is handed over whole.
623
+ */
624
+ acceptError?: boolean;
625
+ /**
626
+ * The argument's subtree may be handed over UNEVALUATED, as an `ILazy` handle the body either
627
+ * returns unread or forces with `getValue()`. Generated from the `Lazy<T>` marker.
628
+ *
629
+ * @remarks
630
+ * A declaration, not a request: the engine defers where it can and DECLINES where it cannot
631
+ * (an absent argument, an async subtree, a lift that needs every arm), handing over a handle
632
+ * that is already full. Either way the body sees a handle and nothing else, which is why the
633
+ * marker is a contract rather than something inferred from what the body happens to read.
634
+ *
635
+ * Only a RESULT position carries it — `IF`'s branches, `CHOOSE`'s arms, `IFERROR`'s fallback.
636
+ * A condition, an index or a case value is eager, so `AND(FALSE,A1)` still reads `A1` and is
637
+ * still a circular reference.
459
638
  *
460
- * - `'accept'`: the body receives `FormulaError` values raw.
461
- * - `'accept-ref'`: per argument SHAPE — reject for a direct/computed argument, accept for a
462
- * reference-shaped one. Resolved to one of the two before any coercion runs, so nothing
463
- * downstream sees this value.
639
+ * {@link defaultValue} is APPLIED at a lazy slot rather than merely recorded: the parameter
640
+ * cannot carry an initializer of its own (`= false` does not typecheck against a handle), so
641
+ * `Lazy<T, V>` declares it and the engine supplies it for an absent argument.
464
642
  *
465
- * OMITTED is the default and the default is REJECT (ErrorPolicy.ts): never call the body — the
466
- * error propagates with its identity (scalar argument), becomes an error member of the output
467
- * (lifted member), or short-circuits on the first error in row-major order (range/array
468
- * member). Only a `FormulaError.Known`-typed parameter receives without a marker, because the
469
- * type declares it. There is no `'reject'` value: it would say what omitting this says.
643
+ * @see {@link Lazy}
470
644
  */
471
- errors?: 'accept' | 'accept-ref';
645
+ lazy?: boolean;
472
646
  /**
473
- * Indicates whether the function requires the address of the calling cell as an input.
474
- * Cannot be combined with `stream`.
647
+ * A multi-cell REFERENCE at this scalar parameter is `#VALUE!` rather than a broadcast.
648
+ * Generated from the `NoLift<T>` marker.
475
649
  *
476
- * @defaultValue `false`
650
+ * @remarks
651
+ * Per parameter, because Excel is: `NETWORKDAYS.INTL` refuses a reference at its date slots
652
+ * and lifts one at `weekend`. An ARRAY at the slot still lifts, a one-cell reference is an
653
+ * ordinary argument, and a repeating slot absorbs a container as members, so the marker only
654
+ * ever applies to a non-repeating scalar parameter.
655
+ */
656
+ noLift?: boolean;
657
+ /**
658
+ * The members reaching this repeating scalar parameter are COERCED rather than filtered, and
659
+ * one that cannot be coerced is `#VALUE!` for the whole call. Generated from the `NoFilter<T>`
660
+ * marker.
661
+ *
662
+ * @remarks
663
+ * Numeric text parses, a blank inside a multi-cell range reads 0, and a boolean or
664
+ * non-numeric text member refuses — Excel's Analysis-ToolPak reading of a repeating slot,
665
+ * where the native family skips all three (`GCD({6,"8",12})` is 2 where `SUM` would answer
666
+ * over 6 and 12 alone). Only a repeating slot has members, so the marker applies nowhere
667
+ * else; a non-repeating scalar's counterpart is {@link noLift}.
668
+ */
669
+ noFilter?: boolean;
670
+ /**
671
+ * The declared type is ADVISORY: the engine delivers it when it can and hands the body the
672
+ * raw argument when it cannot, instead of answering `#VALUE!` at the slot. Generated from the
673
+ * `ReportType<T>` marker.
674
+ *
675
+ * @remarks
676
+ * The type still reaches the function help, the wizard and the linter — it is what the slot
677
+ * means to a caller. It stops being a gate, so the BODY owns every answer the engine would
678
+ * otherwise have given: a union reaches it as `IRange[]`, a value or an error reaches it as
679
+ * itself. See {@link IFunctionArguments.getKindAt} and
680
+ * {@link IFunctionArguments.getAreaCountAt} for the discriminators.
681
+ */
682
+ reportType?: boolean;
683
+ /**
684
+ * The parameter takes EITHER a value or a range — declared as a two-member union of a bare
685
+ * range type and a scalar type (`IRange | Scalar`, `IReferenceRange | number`) — and the
686
+ * marshaller picks the arm by the ARGUMENT's kind: a value, a bare error or a one-cell
687
+ * reference is the scalar arm (dereferenced, coerced to {@link scalar}, its fault raised in
688
+ * argument order like any scalar slot's); a multi-cell reference, an array or a reference
689
+ * union is the range arm, handed over whole. The slot never lifts.
690
+ *
691
+ * @remarks
692
+ * Excel reads a one-cell argument at some array slots as THE ARGUMENT rather than as a
693
+ * one-cell container: `SORT(<#N/A cell>,1,1,<#DIV/0! cell>)` is `#N/A` where
694
+ * `TAKE(<#N/A cell>,<#DIV/0! cell>)` is `#DIV/0!`. The engine's default
695
+ * for a range slot is TAKE's; this flag is SORT's. {@link scalar} and {@link range} each carry
696
+ * their arm, a pair that without this flag reads as a TYPED range (`IRange<number>`).
697
+ */
698
+ valueOrRange?: boolean;
699
+ /**
700
+ * The closed set of values the parameter accepts. Generated from a parameter typed as a
701
+ * TypeScript `enum`, as an alias paired with a same-name `as const` object, or as a union of
702
+ * number or string literals. {@link scalar} carries the members' type.
703
+ *
704
+ * @remarks
705
+ * Parameters that share a declared enum share one `EnumJSON`, by {@link EnumJSON.id}.
477
706
  */
478
- enums?: string[];
707
+ enum?: EnumJSON;
708
+ }
709
+ /**
710
+ * The JSON form of an {@link IEnum}.
711
+ */
712
+ interface EnumJSON {
713
+ /**
714
+ * The declared type name, unique within the declaring module. A union of bare literals has no
715
+ * name, so its id is the values joined by `|`.
716
+ */
717
+ id: string;
718
+ /**
719
+ * Whether the members are numbers or strings. The two never mix.
720
+ */
721
+ type: typeof ScalarType.Number | typeof ScalarType.String;
722
+ /**
723
+ * The members, in declaration order. A union of bare literals names nothing, so each name is
724
+ * the value as text.
725
+ */
726
+ members: [name: string, value: number | string, deprecated?: string | true][];
479
727
  }
480
728
  /**
481
729
  * Describes the runtime return behavior of a function, including modifiers like
@@ -485,6 +733,24 @@ export declare namespace IFunction {
485
733
  * If none are specified, The value will be returned with no special behavior.
486
734
  */
487
735
  interface ReturnTypeJSON extends ValueTypeJSON {
736
+ /**
737
+ * The declared {@link ValueKind} of the result, where the inherited type spellings cannot say
738
+ * it. Generated from the `@returnKind` marker.
739
+ *
740
+ * @remarks
741
+ * A return type is a pair — is the call a REFERENCE, and what is its value kind. Both halves
742
+ * usually derive from the type spellings: {@link ValueTypeJSON.range} `'p'` (an
743
+ * `IReferenceRange` return, which a function whose value paths are casts may also use —
744
+ * `XLOOKUP`, `TAKE`) is `Reference`; `'r'`/`'m'` is `Array`; a concrete
745
+ * {@link ValueTypeJSON.scalar} is that scalar kind; `'*'` or an untyped return follows the
746
+ * value itself. This field overrides the derivation for the one spelling that loses it — a
747
+ * union like `number[] | number[][]` (`ROW`) collapses to `'*'`, yet the function's one-cell
748
+ * answer is a SCALAR (`TYPE(ROW(A1))` is 1 where `TYPE(TRANSPOSE({5}))` is 64).
749
+ *
750
+ * The engine applies the kind at the call exit: a one-cell range result whose declared kind
751
+ * is a scalar is its member value downstream.
752
+ */
753
+ kind?: ValueKind;
488
754
  /**
489
755
  * Indicates the return value is a Promise or Promise-like (i.e., async).
490
756
  * The system will mark the result as pending and re-trigger evaluation once resolved.
@@ -498,6 +764,20 @@ export declare namespace IFunction {
498
764
  * @defaultValue `false`
499
765
  */
500
766
  stream?: boolean;
767
+ /**
768
+ * The result can change with nothing dirty — a cell naming this function recalculates on
769
+ * every pass. Generated from the `Volatile<T>` marker.
770
+ *
771
+ * @remarks
772
+ * Collected at COMPILE time from the formula text (`CompiledFormula.hasVolatile`), because
773
+ * that is where Excel decides it: `=IF(TRUE,1,RAND())` recalculates on every idle pass though
774
+ * no branch selects the arm, and with lazy arguments the call never happens for the engine to
775
+ * observe. Sits beside {@link async} and {@link stream} because all three are about WHEN a
776
+ * result arrives rather than what it is.
777
+ *
778
+ * @see {@link Volatile}
779
+ */
780
+ volatile?: boolean;
501
781
  }
502
782
  /**
503
783
  * Contains metadata about a function declaration, including its name, return type, parameters, and additional documentation.
@@ -509,6 +789,20 @@ export declare namespace IFunction {
509
789
  returnType?: ReturnTypeJSON;
510
790
  /** @inheritdoc IFunction.IDeclaration.getParameters */
511
791
  parameters?: ParameterTypeJSON[];
792
+ /**
793
+ * The largest number of arguments a call may carry, from `Repeating<T, Max>` on the variadic
794
+ * parameter. Omitted at the default of 255.
795
+ *
796
+ * @remarks
797
+ * Excel keeps one such number per NAME and compares it against the whole call's argument
798
+ * count in its front end, so a call past it is refused AT ENTRY rather than answered — which
799
+ * is why the cap lives on the declaration and not in a body. It is not derivable from the
800
+ * shape: `STDEV` takes 255 arguments and `STDEV.S`, the same function under its dotted name,
801
+ * takes 254.
802
+ *
803
+ * @defaultValue 255
804
+ */
805
+ maxArguments?: number;
512
806
  /**
513
807
  * Describes the execution context required by the function.
514
808
  *
@@ -586,6 +880,22 @@ export declare namespace IFunction {
586
880
  example?: string;
587
881
  defaultValue?: Scalar;
588
882
  }>;
883
+ /**
884
+ * Describe each enum the function's parameters are limited to, by enum id.
885
+ */
886
+ enums?: Record<string, EnumDescriptorJSON>;
887
+ }
888
+ /**
889
+ * The JSON form of an {@link IEnumDescription}. Every field is optional: an enum with no doc
890
+ * comments has nothing to say, and a language pack may translate any part of one.
891
+ */
892
+ interface EnumDescriptorJSON {
893
+ nameLocal?: string;
894
+ summary?: string;
895
+ members?: Record<string, {
896
+ nameLocal?: string;
897
+ description?: string;
898
+ }>;
589
899
  }
590
900
  /**
591
901
  * Contains extended metadata about a function that is not be directly inferable from the code itself.
@@ -0,0 +1,192 @@
1
+ import { Scalar } from './Scalar';
2
+ import { ValueKind } from './ValueKind';
3
+ import { IRange } from './IRange';
4
+ import { Lambda } from './Lambda';
5
+ /**
6
+ * The current call's arguments, as the body sees them — argument **reflection**.
7
+ *
8
+ * @remarks
9
+ * A declaration answers "what does this parameter mean?", and the marshaller coerces every
10
+ * argument to it. That is right for the overwhelming majority of parameters. What it cannot answer
11
+ * is anything about *this particular call*:
12
+ *
13
+ * - What did the caller write there — a value, a cell, an array, nothing at all?
14
+ * - What was the value BEFORE the parameter's type coerced it?
15
+ * - Was that empty slot an omission, or a blank cell the caller pointed at?
16
+ *
17
+ * Excel has behaviors that turn on exactly those questions, and they cluster at the
18
+ * parameters Excel declares `any` — where there is nothing to express as a type, because Excel
19
+ * declined to express one. `CUMIPMT` refuses a boolean at every slot while `FV` coerces one at
20
+ * every slot; the difference is not the values, it is that `CUMIPMT`'s slots are `any` and its
21
+ * body decides.
22
+ *
23
+ * It is REFLECTION and nothing else — two questions, and no third:
24
+ *
25
+ * | question | answers |
26
+ * | --- | --- |
27
+ * | *what was supplied* | {@link getLength}, {@link getKindAt} |
28
+ * | *what it is* | {@link getRawAt}, {@link getKindAt} |
29
+ *
30
+ * Coercion is deliberately absent. A body that wants a number calls
31
+ * {@link IFormulaContext.parseAsNumber} on the value this hands it — that already takes a value,
32
+ * already propagates an incoming error with its identity, and already answers `#VALUE!` for a
33
+ * boolean, which IS the rule an `any` slot needs. There is no coercion an index can do that a
34
+ * value cannot.
35
+ *
36
+ * Obtained from `FormulaContext.getArgs()`, and valid ONLY while the body that asked for it is
37
+ * running. A body must not retain it across an `await`, a callback, or a nested evaluation — the
38
+ * views are pooled by dispatch depth, so the one at your depth is handed to the next call at that
39
+ * depth.
40
+ *
41
+ * ```typescript
42
+ * export function CUMIPMT(rate: Scalar, nper: Scalar): number {
43
+ * const args = FormulaContext.getArgs();
44
+ * if (args.getKindAt(0) === ValueKind.Omitted) return FormulaError.BuiltIn.NA; // `CUMIPMT(,120,…)`
45
+ * const asNumber = FormulaContext.parseAsNumber(args.getRawAt(0) as Scalar); // TRUE is #VALUE!
46
+ * // …
47
+ * }
48
+ * ```
49
+ *
50
+ * @see {@link IFormulaContext.getArgs}
51
+ */
52
+ export interface IFunctionArguments {
53
+ /**
54
+ * How many PARAMETERS the caller supplied.
55
+ *
56
+ * @remarks
57
+ * Indexing throughout matches the BODY's own signature, never the raw call positions
58
+ * (see {@link getRawAt}). `index >= getLength()` is an ABSENT argument — one the caller never
59
+ * wrote, whose own JS initializer supplied the value. That is a different thing from an OMITTED
60
+ * one; see {@link isOmittedAt}.
61
+ */
62
+ getLength(): number;
63
+ /**
64
+ * This invocation's value at `index`, uncoerced.
65
+ *
66
+ * @param index The PARAMETER index — the position in the body's own signature.
67
+ *
68
+ * @remarks
69
+ * A `Scalar` means the argument IS a value; an {@link IRange} means a container whose members
70
+ * the body reads itself (a reference materializes on demand); a {@link Lambda} means a callable.
71
+ *
72
+ * At a REPEATING parameter (`Repeating<T>`, or a rest parameter) this is the ARRAY of that
73
+ * group's values — one entry per argument the caller wrote — and {@link getRepeatingArgsAt} is the
74
+ * per-argument view of the same thing. Indexing by parameter rather than by call position is
75
+ * what lets a body ask its questions in the vocabulary it declared:
76
+ *
77
+ * ```typescript
78
+ * // IFS(condition: Repeating<[logicalTest: boolean, logicalTrue: AcceptError<any>]>)
79
+ * args.getRawAt(0); // [test1, value1, test2, value2, …]
80
+ * args.getRepeatingArgsAt(0).getRawAt(0); // test1
81
+ * ```
82
+ *
83
+ * **Under a lift** the call broadcasts and the body runs once per output cell; this reports the
84
+ * value for THIS invocation — the member at the current broadcast position for a lifted argument,
85
+ * the whole argument for one that is not lifting. That is what every identified caller wants: a
86
+ * body checking for a boolean must see the member, not the array around it.
87
+ *
88
+ * One boundary is worth knowing: under a lift at a parameter that declares a CONCRETE scalar
89
+ * type, the member has already been converted by that declaration, so the raw and coerced answers
90
+ * coincide there. At the `Scalar` slots this interface exists for, nothing coerces and the value
91
+ * is the member exactly as the caller's range holds it.
92
+ *
93
+ * A reference UNION (`(A1:A3,C1:C3)`) is an array too — one `IReferenceRange` per area — which
94
+ * is how a body whose slot took the areas apart can still tell one argument's union from two
95
+ * arguments (`SUMPRODUCT` refuses the first and accepts the second).
96
+ */
97
+ getRawAt(index: number): IFunctionArguments.RawArg | IFunctionArguments.RawArg[];
98
+ /**
99
+ * A nested view over one REPEATING parameter's arguments, so a body can ask the same questions
100
+ * one level down — `getRepeatingArgsAt(0).isOmittedAt(1)`.
101
+ *
102
+ * @param index The PARAMETER index of the repeating group (or rest parameter).
103
+ *
104
+ * @remarks
105
+ * The nested view is FLAT over the group's arguments: a period-2 group repeated three times reads
106
+ * as six, in call order. That is where "which one was omitted" has an answer at all — the group
107
+ * as a whole cannot be omitted, only one of its arguments can.
108
+ *
109
+ * At a non-repeating parameter this returns an EMPTY view (`getLength()` of 0) rather than
110
+ * throwing, so a body that folds over its groups needs no special case.
111
+ */
112
+ getRepeatingArgsAt(index: number): IFunctionArguments;
113
+ /**
114
+ * The KIND of the argument at `index` — the total discriminator over {@link getRawAt}'s value.
115
+ *
116
+ * @param index The PARAMETER index — the position in the body's own signature.
117
+ *
118
+ * @remarks
119
+ * Every raw argument is exactly one of a closed set of kinds ({@link ValueKind}), and this
120
+ * answers without materializing anything — a reference stays coords underneath. The scalar
121
+ * kinds ARE `ScalarType` values, so `getKindAt(i) === ScalarType.Boolean` reads naturally.
122
+ *
123
+ * Under a lift this reports THIS invocation's value, like {@link getRawAt} — except the
124
+ * {@link ValueKind.Omitted} answer, which is a fact about the CALL (the caller wrote an empty
125
+ * comma) and does not change per broadcast position. At a REPEATING parameter it answers for
126
+ * the group's FIRST argument; per-argument kinds are one level down —
127
+ * `getRepeatingArgsAt(i).getKindAt(j)`.
128
+ *
129
+ * There are THREE argument positions:
130
+ *
131
+ * | form | position | answer |
132
+ * | --- | --- | --- |
133
+ * | `CUMIPMT(0.01,120,100000,13,24)` | never wrote a 6th | `Omitted` here — the POSITION fact is {@link getLength} (`index >= getLength()`), not a kind |
134
+ * | `CUMIPMT(,120,100000,13,24,0)` | the empty comma | {@link ValueKind.Omitted} |
135
+ * | `CUMIPMT(…,E1)`, E1 blank | a blank CELL | {@link ValueKind.Reference} — blankness is the cell's value, not the argument |
136
+ *
137
+ * The kind is the argument's own and it survives what it passes through:
138
+ * `VLOOKUP(10,10,1,TRUE)` is `#N/A` where `VLOOKUP(10,{10},1,TRUE)` is 10 — scalar vs 1x1
139
+ * array; `TYPE(IF(TRUE,10))` is 1 where `TYPE(IF(TRUE,{10}))` is 64 — a selector carries the
140
+ * kind through in both directions.
141
+ */
142
+ getKindAt(index: number): ValueKind;
143
+ /**
144
+ * True when the argument at `index` is DIRECT — Excel's "typed into the list of arguments":
145
+ * the evaluated value IS a value, not a container or a callable.
146
+ *
147
+ * @param index The PARAMETER index — the position in the body's own signature.
148
+ *
149
+ * @remarks
150
+ * The derived predicate over {@link getKindAt}: true exactly when the kind is one of the
151
+ * `ScalarType` members. A blank (`ScalarType.Null`) IS a value and is direct; an omitted
152
+ * argument, a reference, an array and a callable are not. Directness is what the
153
+ * direct-vs-member coercion rules key on (`SUM(1,TRUE)` is 2 where `SUM({1,TRUE})` is 1), so
154
+ * a body speaking that vocabulary can ask in it.
155
+ */
156
+ isDirectAt(index: number): boolean;
157
+ /**
158
+ * How many AREAS the argument at `index` covers — 1 for an ordinary reference, more for a
159
+ * union (`(A1:A5,B1:B2)`), and 0 for anything that is not a reference at all.
160
+ *
161
+ * @param index The PARAMETER index — the position in the body's own signature.
162
+ *
163
+ * @remarks
164
+ * {@link getKindAt} deliberately cannot answer this: a union IS a reference and reports
165
+ * {@link ValueKind.Reference}, the same as `A1:A5`. This is the question a body asks when the
166
+ * union is the thing it must decide about, and the three possible answers all come from asking
167
+ * it — flatten every area, refuse, or `#REF!`.
168
+ *
169
+ * Only a {@link IFunction.ParameterTypeJSON.reportType} slot can see a union at all; at every
170
+ * other slot the marshaller has already answered `#VALUE!`.
171
+ */
172
+ getAreaCountAt(index: number): number;
173
+ }
174
+ /**
175
+ * {@inheritDoc IFunctionArguments}
176
+ *
177
+ * @see
178
+ * ### **Interface**
179
+ *
180
+ * {@link IFunctionArguments}
181
+ */
182
+ export declare namespace IFunctionArguments {
183
+ /**
184
+ * One argument as the caller wrote it — a value, a container, a callable, or nothing.
185
+ *
186
+ * @remarks
187
+ * `undefined` is an OMITTED or ABSENT argument; `null` is a blank, which is a value. A reference
188
+ * union is delivered as `RawArg[]` — one reference per area (see {@link IFunctionArguments.getRawAt}).
189
+ */
190
+ type RawArg = Scalar | IRange | Lambda | undefined;
191
+ }
192
+ //# sourceMappingURL=IFunctionArguments.d.ts.map