@codehz/json-expr 0.5.6 → 0.6.1
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.
- package/README.md +16 -25
- package/dist/index.d.mts +191 -186
- package/dist/index.mjs +1117 -839
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ const result = expr({ sum, product })("sum + product");
|
|
|
41
41
|
|
|
42
42
|
// 编译表达式(可序列化为 JSON)
|
|
43
43
|
const compiled = compile(result, { x, y });
|
|
44
|
-
// => [["x", "y"], "$0+$1", "$0*$1", "$2+$3"]
|
|
44
|
+
// => [["x", "y"], "$[0]+$[1]", "$[0]*$[1]", "$[2]+$[3]"]
|
|
45
45
|
|
|
46
46
|
// 执行编译后的表达式
|
|
47
47
|
const value = evaluate(compiled, { x: 2, y: 3 });
|
|
@@ -102,7 +102,7 @@ const array = expr({ x, y })("[x, y].filter(v => v > 0)");
|
|
|
102
102
|
// 其中 $N 用于引用之前的变量或表达式
|
|
103
103
|
|
|
104
104
|
const compiled = compile(result, { x, y });
|
|
105
|
-
// [["x", "y"], "$0+$1", "$0*$1", "$2+$3"]
|
|
105
|
+
// [["x", "y"], "$[0]+$[1]", "$[0]*$[1]", "$[2]+$[3]"]
|
|
106
106
|
```
|
|
107
107
|
|
|
108
108
|
## API 参考
|
|
@@ -156,7 +156,6 @@ const result = expr({ sum, x })("sum * x");
|
|
|
156
156
|
- `variables` - 表达式中使用的所有变量映射或数组
|
|
157
157
|
- `options` - 编译选项(可选)
|
|
158
158
|
- `inline?: boolean` - 是否启用内联优化,将只被引用一次的子表达式内联到使用位置(默认:true)
|
|
159
|
-
- `shortCircuit?: boolean` - 是否启用短路求值,为 &&, ||, ??, 和三元表达式生成控制流节点(默认:true)
|
|
160
159
|
|
|
161
160
|
**返回值:** CompiledData 数组
|
|
162
161
|
|
|
@@ -170,15 +169,11 @@ const product = expr({ x, y })("x * y");
|
|
|
170
169
|
const result = expr({ sum, product })("sum + product");
|
|
171
170
|
|
|
172
171
|
const compiled = compile(result, { x, y });
|
|
173
|
-
// [["x", "y"], "$0+$1", "$0*$1", "$2+$3"]
|
|
172
|
+
// [["x", "y"], "$[0]+$[1]", "$[0]*$[1]", "$[2]+$[3]"]
|
|
174
173
|
|
|
175
174
|
// 禁用内联优化
|
|
176
175
|
const noInline = compile(result, { x, y }, { inline: false });
|
|
177
|
-
// [["x", "y"], "$0+$1", "$0*$1", "$2+$3"]
|
|
178
|
-
|
|
179
|
-
// 禁用短路求值
|
|
180
|
-
const noShortCircuit = compile(result, { x, y }, { shortCircuit: false });
|
|
181
|
-
// 生成的表达式将使用直接的运算符而非控制流节点
|
|
176
|
+
// [["x", "y"], "$[0]+$[1]", "$[0]*$[1]", "$[2]+$[3]"]
|
|
182
177
|
```
|
|
183
178
|
|
|
184
179
|
### `evaluate<TResult>(data: CompiledData, values: Record<string, unknown>): TResult`
|
|
@@ -601,11 +596,11 @@ const b = variable<boolean>();
|
|
|
601
596
|
|
|
602
597
|
// 逻辑或短路
|
|
603
598
|
const orExpr = expr({ a, b })("a || b");
|
|
604
|
-
const compiled = compile(orExpr, { a, b }
|
|
599
|
+
const compiled = compile(orExpr, { a, b });
|
|
605
600
|
|
|
606
601
|
// 当 a 为 true 时,b 不会被求值
|
|
607
602
|
// 编译数据包含控制流节点:
|
|
608
|
-
// [["a", "b"], ["br", "$0", 1], "$1", ["phi"]]
|
|
603
|
+
// [["a", "b"], ["br", "$[0]", 1], "$[1]", ["phi"]]
|
|
609
604
|
|
|
610
605
|
// 空值合并
|
|
611
606
|
const x = variable<number | null>();
|
|
@@ -632,8 +627,8 @@ const product = expr({ x, y })("x * y");
|
|
|
632
627
|
const result = expr({ sum, product })("sum + product");
|
|
633
628
|
|
|
634
629
|
// 自动内联后,编译结果为:
|
|
635
|
-
// [["x", "y"], "($0+$1)+($0*$1)"]
|
|
636
|
-
// 而不是 [["x", "y"], "$0+$1", "$0*$1", "$2+$3"]
|
|
630
|
+
// [["x", "y"], "($[0]+$[1])+($[0]*$[1])"]
|
|
631
|
+
// 而不是 [["x", "y"], "$[0]+$[1]", "$[0]*$[1]", "$[2]+$[3]"]
|
|
637
632
|
|
|
638
633
|
const compiled = compile(result, { x, y });
|
|
639
634
|
const value = evaluate(compiled, { x: 2, y: 3 });
|
|
@@ -670,7 +665,7 @@ const compiled = compile(result, { x, y });
|
|
|
670
665
|
|
|
671
666
|
// 序列化
|
|
672
667
|
const json = JSON.stringify(compiled);
|
|
673
|
-
// "[["x","y"],"$0+$1","$0*$1","$2+$3"]"
|
|
668
|
+
// "[["x","y"],"$[0]+$[1]","$[0]*$[1]","$[2]+$[3]"]"
|
|
674
669
|
|
|
675
670
|
// 存储或传输...
|
|
676
671
|
|
|
@@ -693,8 +688,8 @@ const sum = expr({ x, y })("x + y");
|
|
|
693
688
|
const compiled = compile(sum, { x, y });
|
|
694
689
|
|
|
695
690
|
// 输出
|
|
696
|
-
// [["x", "y"], "$0+$1"]
|
|
697
|
-
// $0 引用 x,$1 引用 y
|
|
691
|
+
// [["x", "y"], "$[0]+$[1]"]
|
|
692
|
+
// $[0] 引用 x,$[1] 引用 y
|
|
698
693
|
```
|
|
699
694
|
|
|
700
695
|
### V2 格式(控制流节点)
|
|
@@ -704,13 +699,13 @@ const compiled = compile(sum, { x, y });
|
|
|
704
699
|
```typescript
|
|
705
700
|
// 输入
|
|
706
701
|
const result = expr({ a, b })("a || b");
|
|
707
|
-
const compiled = compile(result, { a, b }
|
|
702
|
+
const compiled = compile(result, { a, b });
|
|
708
703
|
|
|
709
704
|
// 输出
|
|
710
705
|
// [
|
|
711
706
|
// ["a", "b"],
|
|
712
|
-
// ["br", "$0", 1], // 如果 $0 为 truthy,跳过 1 条指令
|
|
713
|
-
// "$1", // 否则求值 $1
|
|
707
|
+
// ["br", "$[0]", 1], // 如果 $[0] 为 truthy,跳过 1 条指令
|
|
708
|
+
// "$[1]", // 否则求值 $[1]
|
|
714
709
|
// ["phi"] // 取最近求值结果
|
|
715
710
|
// ]
|
|
716
711
|
```
|
|
@@ -741,7 +736,7 @@ const xy = variable<number>();
|
|
|
741
736
|
const conflict = expr({ xy, x })("xy + x");
|
|
742
737
|
// 正确处理:编译器能区分 xy 和 x
|
|
743
738
|
const compiled = compile(conflict, { xy, x });
|
|
744
|
-
// => [["xy", "x"], "$0+$1"]
|
|
739
|
+
// => [["xy", "x"], "$[0]+$[1]"]
|
|
745
740
|
```
|
|
746
741
|
|
|
747
742
|
### 运行时错误
|
|
@@ -895,11 +890,7 @@ const discount = evaluate(rule, {
|
|
|
895
890
|
evaluate(compiled, values2);
|
|
896
891
|
```
|
|
897
892
|
|
|
898
|
-
2.
|
|
899
|
-
|
|
900
|
-
```typescript
|
|
901
|
-
compile(expression, variables, { shortCircuit: true });
|
|
902
|
-
```
|
|
893
|
+
2. **利用短路求值**:短路求值已默认启用,对于条件表达式可以避免不必要的计算
|
|
903
894
|
|
|
904
895
|
3. **利用自动内联**:编译器会自动内联只引用一次的子表达式,无需手动优化
|
|
905
896
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
//#region src/types.d.ts
|
|
2
|
+
declare const ProxyExpression: unique symbol;
|
|
2
3
|
/**
|
|
3
4
|
* Proxy Expression 类型标记(用于类型推导)
|
|
4
5
|
* 这是一个 phantom type,实际运行时是 Proxy 对象
|
|
5
6
|
*/
|
|
6
7
|
type ProxyExpression<T = unknown> = {
|
|
7
|
-
readonly
|
|
8
|
+
readonly [ProxyExpression]: T;
|
|
8
9
|
};
|
|
10
|
+
/**
|
|
11
|
+
* 特殊全局类型 - 这些类型作为参数时允许直接传入原始值
|
|
12
|
+
* 不需要递归展开其属性
|
|
13
|
+
*/
|
|
14
|
+
type BuiltinObjects = Date | RegExp | Error | URL | URLSearchParams | ArrayBuffer | SharedArrayBuffer | DataView | Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
|
|
15
|
+
/**
|
|
16
|
+
* 将数组/元组类型的每个元素转换为 ProxifyArg
|
|
17
|
+
* 保留元组的结构信息
|
|
18
|
+
*/
|
|
19
|
+
type ProxifyArgTuple<T extends readonly unknown[]> = T extends readonly [infer Head, ...infer Tail] ? [ProxifyArg<Head>, ...ProxifyArgTuple<Tail>] : T extends readonly [] ? [] : T extends readonly (infer E)[] ? readonly ProxifyArg<E>[] : never;
|
|
20
|
+
type ProxifyArg<T> = Proxify<T> | (T extends BuiltinObjects | string | number | boolean | bigint | undefined | null ? T : T extends readonly unknown[] ? ProxifyArgTuple<T> : T extends Map<infer K, infer V> ? Map<ProxifyArg<K>, ProxifyArg<V>> : T extends Set<infer E> ? Set<ProxifyArg<E>> : T extends WeakMap<infer K, infer V> ? WeakMap<ProxifyArg<K>, ProxifyArg<V>> : T extends WeakSet<infer E> ? WeakSet<ProxifyArg<E>> : T extends Promise<infer R> ? Promise<ProxifyArg<R>> : T extends ((...args: infer _A) => infer _R) ? never : { [K in keyof T]: ProxifyArg<T[K]> });
|
|
9
21
|
/**
|
|
10
22
|
* 处理函数参数的 Proxy 转换
|
|
11
23
|
* 参数可以是原始值或对应的 Proxy
|
|
12
24
|
*/
|
|
13
|
-
type ProxifyArgs<T extends unknown[]> = { [K in keyof T]:
|
|
25
|
+
type ProxifyArgs<T extends unknown[]> = { [K in keyof T]: ProxifyArg<T[K]> };
|
|
14
26
|
/**
|
|
15
27
|
* 需要保留泛型参数的数组方法名
|
|
16
28
|
* 这些方法需要显式定义以保留类型推导
|
|
@@ -123,9 +135,14 @@ type PhiNode = ["phi"];
|
|
|
123
135
|
*/
|
|
124
136
|
type ControlFlowNode = BranchNode | JumpNode | PhiNode;
|
|
125
137
|
/**
|
|
126
|
-
*
|
|
138
|
+
* Lambda 函数节点
|
|
139
|
+
* ["fn", paramCount, ...stmts]
|
|
127
140
|
*/
|
|
128
|
-
type
|
|
141
|
+
type FnNode = ["fn", paramCount: number, ...stmts: CompiledExpression[]];
|
|
142
|
+
/**
|
|
143
|
+
* 表达式类型(可以是字符串、控制流节点或 Lambda 节点)
|
|
144
|
+
*/
|
|
145
|
+
type CompiledExpression = string | ControlFlowNode | FnNode;
|
|
129
146
|
/**
|
|
130
147
|
* 编译后的可序列化结构
|
|
131
148
|
* 数组形式:[string[], ...expressions[]]
|
|
@@ -134,15 +151,6 @@ type CompiledExpression = string | ControlFlowNode;
|
|
|
134
151
|
* - 表达式可以是字符串或控制流节点(br/jmp/phi)
|
|
135
152
|
*/
|
|
136
153
|
type CompiledData = [variableNames: string[], ...expressions: CompiledExpression[]];
|
|
137
|
-
/**
|
|
138
|
-
* 递归地去除 Proxify 包装
|
|
139
|
-
* 处理嵌套的对象和数组中的所有 Proxy 类型
|
|
140
|
-
* - 如果是 Proxify<T>,提取并返回 UnproxyDeep<T>
|
|
141
|
-
* - 如果是对象,递归处理每个属性
|
|
142
|
-
* - 如果是数组,递归处理元素
|
|
143
|
-
* - 其他情况返回原值
|
|
144
|
-
*/
|
|
145
|
-
type UnproxyDeep<T> = T extends ProxyExpression<infer U> ? UnproxyDeep<U> : T extends readonly (infer E)[] ? UnproxyDeep<E>[] : T extends object ? { [K in keyof T]: UnproxyDeep<T[K]> } : T;
|
|
146
154
|
/**
|
|
147
155
|
* Lambda 参数代理类型
|
|
148
156
|
* 与普通 Proxify<T> 相同,但标记为 lambda 参数
|
|
@@ -185,62 +193,7 @@ type InferLambdaArgs<L> = L extends Lambda<infer Args, unknown> ? Args : never;
|
|
|
185
193
|
*/
|
|
186
194
|
type InferLambdaReturn<L> = L extends Lambda<unknown[], infer R> ? R : never;
|
|
187
195
|
//#endregion
|
|
188
|
-
//#region src/
|
|
189
|
-
/**
|
|
190
|
-
* 编译选项
|
|
191
|
-
*/
|
|
192
|
-
interface CompileOptions {
|
|
193
|
-
/**
|
|
194
|
-
* 是否启用短路求值
|
|
195
|
-
* 为 &&, ||, ??, 和三元表达式生成控制流节点
|
|
196
|
-
* @default true
|
|
197
|
-
*/
|
|
198
|
-
shortCircuit?: boolean;
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* 将 Proxy Expression 编译为可序列化的 JSON 结构
|
|
202
|
-
*
|
|
203
|
-
* @template TResult - 表达式结果类型
|
|
204
|
-
* @param expression - Proxy Expression,或包含 Proxy 的对象/数组/原始值
|
|
205
|
-
* @param variables - 所有使用的变量定义
|
|
206
|
-
* @param options - 编译选项
|
|
207
|
-
* @returns 编译后的数据结构 [变量名列表, 表达式1, 表达式2, ...]
|
|
208
|
-
*
|
|
209
|
-
* @throws 如果传入无效的表达式或未定义的变量引用
|
|
210
|
-
*
|
|
211
|
-
* @example
|
|
212
|
-
* ```ts
|
|
213
|
-
* const x = variable<number>()
|
|
214
|
-
* const y = variable<number>()
|
|
215
|
-
* const sum = expr({ x, y })("x + y")
|
|
216
|
-
* const result = expr({ sum, x })("sum * x")
|
|
217
|
-
* const compiled = compile(result, { x, y })
|
|
218
|
-
* // => [["x", "y"], "($0+$1)*$0"]
|
|
219
|
-
* ```
|
|
220
|
-
*/
|
|
221
|
-
declare function compile<TResult>(expression: ExprValue<TResult>, variables: Record<string, unknown>, options?: CompileOptions): CompiledData;
|
|
222
|
-
//#endregion
|
|
223
|
-
//#region src/evaluate.d.ts
|
|
224
|
-
/**
|
|
225
|
-
* 执行编译后的表达式
|
|
226
|
-
*
|
|
227
|
-
* @template TResult - 表达式结果类型
|
|
228
|
-
* @param data - 编译后的数据结构 [变量名列表, 表达式1, 表达式2, ...]
|
|
229
|
-
* @param values - 变量值映射,按变量名提供值
|
|
230
|
-
* @returns 最后一个表达式的求值结果
|
|
231
|
-
*
|
|
232
|
-
* @throws 如果运行时类型验证失败或表达式执行出错
|
|
233
|
-
*
|
|
234
|
-
* @example
|
|
235
|
-
* ```ts
|
|
236
|
-
* const compiled = [["x", "y"], "$0+$1", "$1*2"]
|
|
237
|
-
* const result = evaluate<number>(compiled, { x: 2, y: 3 })
|
|
238
|
-
* // => 6 (3 * 2)
|
|
239
|
-
* ```
|
|
240
|
-
*/
|
|
241
|
-
declare function evaluate<TResult = unknown>(data: CompiledData, values: Record<string, unknown>): TResult;
|
|
242
|
-
//#endregion
|
|
243
|
-
//#region src/type-parser.d.ts
|
|
196
|
+
//#region src/types/type-parser/utils.d.ts
|
|
244
197
|
/** 去除字符串两端空白 */
|
|
245
198
|
type TrimStart<S extends string> = S extends ` ${infer Rest}` | `\t${infer Rest}` | `\n${infer Rest}` ? TrimStart<Rest> : S;
|
|
246
199
|
/** 是否是字母或下划线 */
|
|
@@ -249,18 +202,47 @@ type IsIdentifierStart<C extends string> = C extends "a" | "b" | "c" | "d" | "e"
|
|
|
249
202
|
type IsIdentifierChar<C extends string> = IsIdentifierStart<C> extends true ? true : C extends "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ? true : false;
|
|
250
203
|
/** 是否是数字 */
|
|
251
204
|
type IsDigit<C extends string> = C extends "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ? true : false;
|
|
205
|
+
/** 全局类型映射 */
|
|
206
|
+
interface GlobalTypeMap {
|
|
207
|
+
Math: Math;
|
|
208
|
+
JSON: JSON;
|
|
209
|
+
Number: NumberConstructor;
|
|
210
|
+
String: StringConstructor;
|
|
211
|
+
Boolean: BooleanConstructor;
|
|
212
|
+
Array: ArrayConstructor;
|
|
213
|
+
Object: ObjectConstructor;
|
|
214
|
+
Date: DateConstructor;
|
|
215
|
+
RegExp: RegExpConstructor;
|
|
216
|
+
undefined: undefined;
|
|
217
|
+
NaN: number;
|
|
218
|
+
Infinity: number;
|
|
219
|
+
parseInt: typeof globalThis.parseInt;
|
|
220
|
+
parseFloat: typeof globalThis.parseFloat;
|
|
221
|
+
isNaN: typeof globalThis.isNaN;
|
|
222
|
+
isFinite: typeof globalThis.isFinite;
|
|
223
|
+
}
|
|
252
224
|
/** JS保留字和全局对象 */
|
|
253
225
|
type ReservedWords = "true" | "false" | "null" | "undefined" | "if" | "else" | "for" | "while" | "do" | "switch" | "case" | "break" | "continue" | "return" | "function" | "var" | "let" | "const" | "class" | "new" | "this" | "typeof" | "instanceof" | keyof GlobalTypeMap;
|
|
226
|
+
//#endregion
|
|
227
|
+
//#region src/types/type-parser/context.d.ts
|
|
228
|
+
/** 从 Variable 提取值类型 */
|
|
229
|
+
type ExtractType<T> = T extends ProxyExpression<infer V> ? V : T extends Variable<infer V> ? V : never;
|
|
230
|
+
/** 从上下文对象构建类型映射 */
|
|
231
|
+
type ContextTypeMap<TContext> = { [K in keyof TContext]: ExtractType<TContext[K]> };
|
|
232
|
+
/** 找出未定义的标识符 */
|
|
233
|
+
type FindUndefinedIdentifiers<Ids extends string, ContextKeys extends string> = Ids extends ContextKeys ? never : Ids;
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/types/type-parser/identifiers.d.ts
|
|
254
236
|
/** 解析一个标识符,返回 [标识符, 剩余字符串] */
|
|
255
237
|
type ParseIdentifier<S extends string, Acc extends string = ""> = S extends `${infer C}${infer Rest}` ? IsIdentifierChar<C> extends true ? ParseIdentifier<Rest, `${Acc}${C}`> : [Acc, S] : [Acc, S];
|
|
256
238
|
/** 跳过数字字面量 */
|
|
257
239
|
type SkipNumber<S extends string> = S extends `${infer C}${infer Rest}` ? C extends "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "." ? SkipNumber<Rest> : S : S;
|
|
258
240
|
/** 跳过字符串字面量(单引号) */
|
|
259
|
-
type SkipSingleQuoteString<S extends string> = S extends `'${infer Rest}` ? SkipSingleQuoteStringContent<Rest> : S;
|
|
260
|
-
type SkipSingleQuoteStringContent<S extends string> = S extends `\\'${infer Rest}` ? SkipSingleQuoteStringContent<Rest> : S extends `'${infer Rest}` ? Rest : S extends `${string}${infer Rest}` ? SkipSingleQuoteStringContent<Rest> : S;
|
|
241
|
+
type SkipSingleQuoteString<S extends string> = S extends `'${infer Rest}` ? SkipSingleQuoteStringContent$1<Rest> : S;
|
|
242
|
+
type SkipSingleQuoteStringContent$1<S extends string> = S extends `\\'${infer Rest}` ? SkipSingleQuoteStringContent$1<Rest> : S extends `'${infer Rest}` ? Rest : S extends `${string}${infer Rest}` ? SkipSingleQuoteStringContent$1<Rest> : S;
|
|
261
243
|
/** 跳过字符串字面量(双引号) */
|
|
262
|
-
type SkipDoubleQuoteString<S extends string> = S extends `"${infer Rest}` ? SkipDoubleQuoteStringContent<Rest> : S;
|
|
263
|
-
type SkipDoubleQuoteStringContent<S extends string> = S extends `\\"${infer Rest}` ? SkipDoubleQuoteStringContent<Rest> : S extends `"${infer Rest}` ? Rest : S extends `${string}${infer Rest}` ? SkipDoubleQuoteStringContent<Rest> : S;
|
|
244
|
+
type SkipDoubleQuoteString<S extends string> = S extends `"${infer Rest}` ? SkipDoubleQuoteStringContent$1<Rest> : S;
|
|
245
|
+
type SkipDoubleQuoteStringContent$1<S extends string> = S extends `\\"${infer Rest}` ? SkipDoubleQuoteStringContent$1<Rest> : S extends `"${infer Rest}` ? Rest : S extends `${string}${infer Rest}` ? SkipDoubleQuoteStringContent$1<Rest> : S;
|
|
264
246
|
/** 跳过模板字符串 */
|
|
265
247
|
type SkipTemplateString<S extends string> = S extends `\`${infer Rest}` ? SkipTemplateStringContent<Rest> : S;
|
|
266
248
|
type SkipTemplateStringContent<S extends string> = S extends `\\\`${infer Rest}` ? SkipTemplateStringContent<Rest> : S extends `\`${infer Rest}` ? Rest : S extends `${string}${infer Rest}` ? SkipTemplateStringContent<Rest> : S;
|
|
@@ -269,12 +251,8 @@ type SkipTemplateStringContent<S extends string> = S extends `\\\`${infer Rest}`
|
|
|
269
251
|
* 返回标识符的联合类型
|
|
270
252
|
*/
|
|
271
253
|
type ExtractIdentifiers<S extends string, Collected extends string = never> = S extends "" ? Collected : TrimStart<S> extends `${infer Trimmed}` ? Trimmed extends "" ? Collected : Trimmed extends `'${string}` ? ExtractIdentifiers<SkipSingleQuoteString<Trimmed>, Collected> : Trimmed extends `"${string}` ? ExtractIdentifiers<SkipDoubleQuoteString<Trimmed>, Collected> : Trimmed extends `\`${string}` ? ExtractIdentifiers<SkipTemplateString<Trimmed>, Collected> : Trimmed extends `${infer First}${infer Rest}` ? IsIdentifierStart<First> extends true ? ParseIdentifier<Trimmed> extends [infer Id extends string, infer Remaining extends string] ? Id extends ReservedWords ? ExtractIdentifiers<Remaining, Collected> : ExtractIdentifiers<Remaining, Collected | Id> : Collected : IsDigit<First> extends true ? ExtractIdentifiers<SkipNumber<Trimmed>, Collected> : ExtractIdentifiers<Rest, Collected> : Collected : Collected;
|
|
272
|
-
|
|
273
|
-
type
|
|
274
|
-
/** 从上下文对象构建类型映射 */
|
|
275
|
-
type ContextTypeMap<TContext> = { [K in keyof TContext]: ExtractType<TContext[K]> };
|
|
276
|
-
/** 找出未定义的标识符 */
|
|
277
|
-
type FindUndefinedIdentifiers<Ids extends string, ContextKeys extends string> = Ids extends ContextKeys ? never : Ids;
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region src/types/type-parser/ast-types.d.ts
|
|
278
256
|
interface ASTNumber {
|
|
279
257
|
type: "number";
|
|
280
258
|
}
|
|
@@ -335,7 +313,6 @@ interface ASTObject<Props extends Record<string, unknown> = Record<string, unkno
|
|
|
335
313
|
type: "object";
|
|
336
314
|
properties: Props;
|
|
337
315
|
}
|
|
338
|
-
/** 运算符优先级(从低到高) */
|
|
339
316
|
/** 解析结果:[AST, 剩余字符串] */
|
|
340
317
|
type ParseResult<T, Rest extends string> = {
|
|
341
318
|
ast: T;
|
|
@@ -344,6 +321,82 @@ type ParseResult<T, Rest extends string> = {
|
|
|
344
321
|
type ParseError = {
|
|
345
322
|
error: true;
|
|
346
323
|
};
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/types/type-parser/expression-parser.d.ts
|
|
326
|
+
/** 解析数字字面量,返回 [数字字符串, 剩余] */
|
|
327
|
+
type ParseNumberLiteral<S extends string, Acc extends string = ""> = S extends `${infer C}${infer Rest}` ? C extends "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "." ? ParseNumberLiteral<Rest, `${Acc}${C}`> : [Acc, S] : [Acc, S];
|
|
328
|
+
/** 解析字符串字面量 */
|
|
329
|
+
type ParseStringLiteral<S extends string> = S extends `'${infer __}` ? {
|
|
330
|
+
rest: SkipSingleQuoteString<S>;
|
|
331
|
+
} : S extends `"${infer __}` ? {
|
|
332
|
+
rest: SkipDoubleQuoteString<S>;
|
|
333
|
+
} : S extends `\`${infer __}` ? {
|
|
334
|
+
rest: SkipTemplateString<S>;
|
|
335
|
+
} : never;
|
|
336
|
+
/** 解析数组字面量 */
|
|
337
|
+
type ParseArrayLiteral<S extends string, Elements extends unknown[] = []> = TrimStart<S> extends `]${infer Rest}` ? ParseResult<ASTArray<Elements>, Rest> : ParseTernary<S> extends ParseResult<infer Element, infer Rest> ? TrimStart<Rest> extends `,${infer Rest2}` ? ParseArrayLiteral<Rest2, [...Elements, Element]> : TrimStart<Rest> extends `]${infer Rest2}` ? ParseResult<ASTArray<[...Elements, Element]>, Rest2> : ParseError : ParseError;
|
|
338
|
+
/** 解析对象属性键 */
|
|
339
|
+
type ParseObjectKey<S extends string> = TrimStart<S> extends `'${infer _}` ? SkipSingleQuoteStringContent<TrimStart<S> extends `'${infer Rest}` ? Rest : never> extends `${infer Rest}` ? TrimStart<S> extends `'${infer Key}'${infer _Rest}` ? {
|
|
340
|
+
key: Key;
|
|
341
|
+
rest: Rest;
|
|
342
|
+
} : never : never : TrimStart<S> extends `"${infer _}` ? SkipDoubleQuoteStringContent<TrimStart<S> extends `"${infer Rest}` ? Rest : never> extends `${infer Rest}` ? TrimStart<S> extends `"${infer Key}"${infer _Rest}` ? {
|
|
343
|
+
key: Key;
|
|
344
|
+
rest: Rest;
|
|
345
|
+
} : never : never : ParseIdentifier<TrimStart<S>> extends [infer Key extends string, infer Rest extends string] ? Key extends "" ? never : {
|
|
346
|
+
key: Key;
|
|
347
|
+
rest: Rest;
|
|
348
|
+
} : never;
|
|
349
|
+
type SkipSingleQuoteStringContent<S extends string> = S extends `\\'${infer Rest}` ? SkipSingleQuoteStringContent<Rest> : S extends `'${infer Rest}` ? Rest : S extends `${string}${infer Rest}` ? SkipSingleQuoteStringContent<Rest> : S;
|
|
350
|
+
type SkipDoubleQuoteStringContent<S extends string> = S extends `\\"${infer Rest}` ? SkipDoubleQuoteStringContent<Rest> : S extends `"${infer Rest}` ? Rest : S extends `${string}${infer Rest}` ? SkipDoubleQuoteStringContent<Rest> : S;
|
|
351
|
+
/** 解析对象字面量 */
|
|
352
|
+
type ParseObjectLiteral<S extends string, Props extends Record<string, unknown> = {}> = TrimStart<S> extends `}${infer Rest}` ? ParseResult<ASTObject<Props>, Rest> : ParseObjectKey<S> extends {
|
|
353
|
+
key: infer Key extends string;
|
|
354
|
+
rest: infer Rest1 extends string;
|
|
355
|
+
} ? TrimStart<Rest1> extends `:${infer Rest2}` ? ParseTernary<Rest2> extends ParseResult<infer Value, infer Rest3> ? TrimStart<Rest3> extends `,${infer Rest4}` ? ParseObjectLiteral<Rest4, Props & Record<Key, Value>> : TrimStart<Rest3> extends `}${infer Rest4}` ? ParseResult<ASTObject<Props & Record<Key, Value>>, Rest4> : ParseError : ParseError : ParseError : ParseError;
|
|
356
|
+
/** 解析标识符主表达式 */
|
|
357
|
+
type ParseIdentifierPrimary<S extends string> = ParseIdentifier<TrimStart<S>> extends [infer Name extends string, infer Rest extends string] ? Name extends "" ? ParseError : ParseResult<ASTIdentifier<Name>, Rest> : ParseError;
|
|
358
|
+
/** 解析主表达式 */
|
|
359
|
+
type ParsePrimary<S extends string> = TrimStart<S> extends `(${infer Rest}` ? ParseTernary<Rest> extends ParseResult<infer Inner, infer Rest2> ? TrimStart<Rest2> extends `)${infer Rest3}` ? ParseResult<ASTParen<Inner>, Rest3> : ParseError : ParseError : TrimStart<S> extends `[${infer Rest}` ? ParseArrayLiteral<Rest> : TrimStart<S> extends `{${infer Rest}` ? ParseObjectLiteral<Rest> : TrimStart<S> extends `true${infer Rest}` ? IsIdentifierChar<Rest extends `${infer C}${string}` ? C : ""> extends true ? ParseIdentifierPrimary<S> : ParseResult<ASTBoolean, Rest> : TrimStart<S> extends `false${infer Rest}` ? IsIdentifierChar<Rest extends `${infer C}${string}` ? C : ""> extends true ? ParseIdentifierPrimary<S> : ParseResult<ASTBoolean, Rest> : TrimStart<S> extends `${infer C}${infer __Rest}` ? IsDigit<C> extends true ? ParseNumberLiteral<TrimStart<S>> extends [infer __Num, infer Rest2 extends string] ? ParseResult<ASTNumber, Rest2> : ParseError : C extends "-" ? TrimStart<__Rest> extends `${infer C2}${string}` ? IsDigit<C2> extends true ? ParseNumberLiteral<TrimStart<__Rest>> extends [infer __Num, infer Rest2 extends string] ? ParseResult<ASTNumber, Rest2> : ParseError : ParseError : ParseError : C extends "'" | '"' | "`" ? ParseStringLiteral<TrimStart<S>> extends {
|
|
360
|
+
rest: infer Rest2 extends string;
|
|
361
|
+
} ? ParseResult<ASTString, Rest2> : ParseError : IsIdentifierStart<C> extends true ? ParseIdentifierPrimary<S> : ParseError : ParseError;
|
|
362
|
+
/** 解析后缀运算符入口 */
|
|
363
|
+
type ParsePostfix<S extends string> = ParsePrimary<TrimStart<S>> extends ParseResult<infer Base, infer Rest> ? ParsePostfixTail<Base, Rest> : ParseError;
|
|
364
|
+
/** 解析后缀运算符尾部 */
|
|
365
|
+
type ParsePostfixTail<Base, S extends string> = TrimStart<S> extends `.${infer Rest}` ? ParseIdentifier<TrimStart<Rest>> extends [infer Prop extends string, infer Rest2 extends string] ? Prop extends "" ? ParseResult<Base, S> : ParsePostfixTail<ASTMemberAccess<Base, Prop>, Rest2> : ParseResult<Base, S> : TrimStart<S> extends `[${infer Rest}` ? ParseTernary<Rest> extends ParseResult<infer Index, infer Rest2> ? TrimStart<Rest2> extends `]${infer Rest3}` ? ParsePostfixTail<ASTComputedMember<Base, Index>, Rest3> : ParseResult<Base, S> : ParseResult<Base, S> : TrimStart<S> extends `(${infer Rest}` ? ParseCallArgs<Rest> extends {
|
|
366
|
+
args: infer Args extends unknown[];
|
|
367
|
+
rest: infer Rest2 extends string;
|
|
368
|
+
} ? ParsePostfixTail<ASTCall<Base, Args>, Rest2> : ParseResult<Base, S> : ParseResult<Base, S>;
|
|
369
|
+
/** 解析函数调用参数 */
|
|
370
|
+
type ParseCallArgs<S extends string, Args extends unknown[] = []> = TrimStart<S> extends `)${infer Rest}` ? {
|
|
371
|
+
args: Args;
|
|
372
|
+
rest: Rest;
|
|
373
|
+
} : ParseTernary<S> extends ParseResult<infer Arg, infer Rest> ? TrimStart<Rest> extends `,${infer Rest2}` ? ParseCallArgs<Rest2, [...Args, Arg]> : TrimStart<Rest> extends `)${infer Rest2}` ? {
|
|
374
|
+
args: [...Args, Arg];
|
|
375
|
+
rest: Rest2;
|
|
376
|
+
} : {
|
|
377
|
+
args: Args;
|
|
378
|
+
rest: S;
|
|
379
|
+
} : {
|
|
380
|
+
args: Args;
|
|
381
|
+
rest: S;
|
|
382
|
+
};
|
|
383
|
+
/** 运算符优先级(从低到高):
|
|
384
|
+
* Level 1: ?: (三元)
|
|
385
|
+
* Level 2: ?? (空值合并)
|
|
386
|
+
* Level 3: || (逻辑或)
|
|
387
|
+
* Level 4: && (逻辑与)
|
|
388
|
+
* Level 5: | (位或)
|
|
389
|
+
* Level 6: ^ (位异或)
|
|
390
|
+
* Level 7: & (位与)
|
|
391
|
+
* Level 8: ==, !=, ===, !== (相等)
|
|
392
|
+
* Level 9: <, >, <=, >= (比较)
|
|
393
|
+
* Level 10: <<, >>, >>> (位移)
|
|
394
|
+
* Level 11: +, - (加减)
|
|
395
|
+
* Level 12: *, /, % (乘除)
|
|
396
|
+
* Level 13: ** (幂运算,右结合)
|
|
397
|
+
* Level 14: 一元运算符
|
|
398
|
+
* Level 15: 成员访问、函数调用
|
|
399
|
+
*/
|
|
347
400
|
/** 解析三元表达式(最低优先级)- 右结合 */
|
|
348
401
|
type ParseTernary<S extends string> = ParseLogicalOr<TrimStart<S>> extends ParseResult<infer Left, infer Rest1> ? TrimStart<Rest1> extends `?${infer AfterQ}` ? ParseTernary<AfterQ> extends ParseResult<infer Then, infer Rest2> ? TrimStart<Rest2> extends `:${infer AfterColon}` ? ParseTernary<AfterColon> extends ParseResult<infer Else, infer Rest3> ? ParseResult<ASTTernary<Left, Then, Else>, Rest3> : ParseResult<Left, Rest1> : ParseResult<Left, Rest1> : ParseResult<Left, Rest1> : ParseResult<Left, Rest1> : ParseError;
|
|
349
402
|
/** 解析逻辑或 || */
|
|
@@ -384,60 +437,10 @@ type ParseExponentiation<S extends string> = ParseUnary<TrimStart<S>> extends Pa
|
|
|
384
437
|
type ParseExponentiationTail<Left, S extends string> = TrimStart<S> extends `**${infer Rest}` ? ParseExponentiation<Rest> extends ParseResult<infer Right, infer Rest2> ? ParseResult<ASTBinary<"**", Left, Right>, Rest2> : ParseResult<Left, S> : ParseResult<Left, S>;
|
|
385
438
|
/** 解析一元运算符 */
|
|
386
439
|
type ParseUnary<S extends string> = TrimStart<S> extends `!${infer Rest}` ? ParseUnary<Rest> extends ParseResult<infer Operand, infer Rest2> ? ParseResult<ASTUnary<"!", Operand>, Rest2> : ParseError : TrimStart<S> extends `~${infer Rest}` ? ParseUnary<Rest> extends ParseResult<infer Operand, infer Rest2> ? ParseResult<ASTUnary<"~", Operand>, Rest2> : ParseError : TrimStart<S> extends `typeof${infer Rest}` ? IsIdentifierChar<Rest extends `${infer C}${string}` ? C : ""> extends true ? ParseError : ParseUnary<Rest> extends ParseResult<infer Operand, infer Rest2> ? ParseResult<ASTUnary<"typeof", Operand>, Rest2> : ParseError : TrimStart<S> extends `void${infer Rest}` ? IsIdentifierChar<Rest extends `${infer C}${string}` ? C : ""> extends true ? ParseError : ParseUnary<Rest> extends ParseResult<infer Operand, infer Rest2> ? ParseResult<ASTUnary<"void", Operand>, Rest2> : ParseError : TrimStart<S> extends `-${infer Rest}` ? IsDigit<Rest extends `${infer C}${string}` ? C : ""> extends true ? ParsePostfix<S> : ParseUnary<Rest> extends ParseResult<infer Operand, infer Rest2> ? ParseResult<ASTUnary<"-", Operand>, Rest2> : ParseError : TrimStart<S> extends `+${infer Rest}` ? ParseUnary<Rest> extends ParseResult<infer Operand, infer Rest2> ? ParseResult<ASTUnary<"+", Operand>, Rest2> : ParseError : ParsePostfix<S>;
|
|
387
|
-
/** 解析后缀运算符(成员访问、函数调用) */
|
|
388
|
-
type ParsePostfix<S extends string> = ParsePrimary<TrimStart<S>> extends ParseResult<infer Base, infer Rest> ? ParsePostfixTail<Base, Rest> : ParseError;
|
|
389
|
-
type ParsePostfixTail<Base, S extends string> = TrimStart<S> extends `.${infer Rest}` ? ParseIdentifier<TrimStart<Rest>> extends [infer Prop extends string, infer Rest2 extends string] ? Prop extends "" ? ParseResult<Base, S> : ParsePostfixTail<ASTMemberAccess<Base, Prop>, Rest2> : ParseResult<Base, S> : TrimStart<S> extends `[${infer Rest}` ? ParseTernary<Rest> extends ParseResult<infer Index, infer Rest2> ? TrimStart<Rest2> extends `]${infer Rest3}` ? ParsePostfixTail<ASTComputedMember<Base, Index>, Rest3> : ParseResult<Base, S> : ParseResult<Base, S> : TrimStart<S> extends `(${infer Rest}` ? ParseCallArgs<Rest> extends {
|
|
390
|
-
args: infer Args extends unknown[];
|
|
391
|
-
rest: infer Rest2 extends string;
|
|
392
|
-
} ? ParsePostfixTail<ASTCall<Base, Args>, Rest2> : ParseResult<Base, S> : ParseResult<Base, S>;
|
|
393
|
-
/** 解析函数调用参数 */
|
|
394
|
-
type ParseCallArgs<S extends string, Args extends unknown[] = []> = TrimStart<S> extends `)${infer Rest}` ? {
|
|
395
|
-
args: Args;
|
|
396
|
-
rest: Rest;
|
|
397
|
-
} : ParseTernary<S> extends ParseResult<infer Arg, infer Rest> ? TrimStart<Rest> extends `,${infer Rest2}` ? ParseCallArgs<Rest2, [...Args, Arg]> : TrimStart<Rest> extends `)${infer Rest2}` ? {
|
|
398
|
-
args: [...Args, Arg];
|
|
399
|
-
rest: Rest2;
|
|
400
|
-
} : {
|
|
401
|
-
args: Args;
|
|
402
|
-
rest: S;
|
|
403
|
-
} : {
|
|
404
|
-
args: Args;
|
|
405
|
-
rest: S;
|
|
406
|
-
};
|
|
407
|
-
/** 解析数字字面量,返回 [数字字符串, 剩余] */
|
|
408
|
-
type ParseNumberLiteral<S extends string, Acc extends string = ""> = S extends `${infer C}${infer Rest}` ? C extends "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "." ? ParseNumberLiteral<Rest, `${Acc}${C}`> : [Acc, S] : [Acc, S];
|
|
409
|
-
/** 解析数组字面量 */
|
|
410
|
-
type ParseArrayLiteral<S extends string, Elements extends unknown[] = []> = TrimStart<S> extends `]${infer Rest}` ? ParseResult<ASTArray<Elements>, Rest> : ParseTernary<S> extends ParseResult<infer Element, infer Rest> ? TrimStart<Rest> extends `,${infer Rest2}` ? ParseArrayLiteral<Rest2, [...Elements, Element]> : TrimStart<Rest> extends `]${infer Rest2}` ? ParseResult<ASTArray<[...Elements, Element]>, Rest2> : ParseError : ParseError;
|
|
411
|
-
/** 解析对象属性键 */
|
|
412
|
-
type ParseObjectKey<S extends string> = TrimStart<S> extends `'${infer _}` ? SkipSingleQuoteStringContent<TrimStart<S> extends `'${infer Rest}` ? Rest : never> extends `${infer Rest}` ? TrimStart<S> extends `'${infer Key}'${infer _Rest}` ? {
|
|
413
|
-
key: Key;
|
|
414
|
-
rest: Rest;
|
|
415
|
-
} : never : never : TrimStart<S> extends `"${infer _}` ? SkipDoubleQuoteStringContent<TrimStart<S> extends `"${infer Rest}` ? Rest : never> extends `${infer Rest}` ? TrimStart<S> extends `"${infer Key}"${infer _Rest}` ? {
|
|
416
|
-
key: Key;
|
|
417
|
-
rest: Rest;
|
|
418
|
-
} : never : never : ParseIdentifier<TrimStart<S>> extends [infer Key extends string, infer Rest extends string] ? Key extends "" ? never : {
|
|
419
|
-
key: Key;
|
|
420
|
-
rest: Rest;
|
|
421
|
-
} : never;
|
|
422
|
-
/** 解析对象字面量 */
|
|
423
|
-
type ParseObjectLiteral<S extends string, Props extends Record<string, unknown> = {}> = TrimStart<S> extends `}${infer Rest}` ? ParseResult<ASTObject<Props>, Rest> : ParseObjectKey<S> extends {
|
|
424
|
-
key: infer Key extends string;
|
|
425
|
-
rest: infer Rest1 extends string;
|
|
426
|
-
} ? TrimStart<Rest1> extends `:${infer Rest2}` ? ParseTernary<Rest2> extends ParseResult<infer Value, infer Rest3> ? TrimStart<Rest3> extends `,${infer Rest4}` ? ParseObjectLiteral<Rest4, Props & Record<Key, Value>> : TrimStart<Rest3> extends `}${infer Rest4}` ? ParseResult<ASTObject<Props & Record<Key, Value>>, Rest4> : ParseError : ParseError : ParseError : ParseError;
|
|
427
|
-
/** 解析主表达式 */
|
|
428
|
-
type ParsePrimary<S extends string> = TrimStart<S> extends `(${infer Rest}` ? ParseTernary<Rest> extends ParseResult<infer Inner, infer Rest2> ? TrimStart<Rest2> extends `)${infer Rest3}` ? ParseResult<ASTParen<Inner>, Rest3> : ParseError : ParseError : TrimStart<S> extends `[${infer Rest}` ? ParseArrayLiteral<Rest> : TrimStart<S> extends `{${infer Rest}` ? ParseObjectLiteral<Rest> : TrimStart<S> extends `true${infer Rest}` ? IsIdentifierChar<Rest extends `${infer C}${string}` ? C : ""> extends true ? ParseIdentifierPrimary<S> : ParseResult<ASTBoolean, Rest> : TrimStart<S> extends `false${infer Rest}` ? IsIdentifierChar<Rest extends `${infer C}${string}` ? C : ""> extends true ? ParseIdentifierPrimary<S> : ParseResult<ASTBoolean, Rest> : TrimStart<S> extends `${infer C}${infer __Rest}` ? IsDigit<C> extends true ? ParseNumberLiteral<TrimStart<S>> extends [infer __Num, infer Rest2 extends string] ? ParseResult<ASTNumber, Rest2> : ParseError : C extends "-" ? TrimStart<__Rest> extends `${infer C2}${string}` ? IsDigit<C2> extends true ? ParseNumberLiteral<TrimStart<__Rest>> extends [infer __Num, infer Rest2 extends string] ? ParseResult<ASTNumber, Rest2> : ParseError : ParseError : ParseError : C extends "'" | '"' | "`" ? ParseStringLiteral<TrimStart<S>> extends {
|
|
429
|
-
rest: infer Rest2 extends string;
|
|
430
|
-
} ? ParseResult<ASTString, Rest2> : ParseError : IsIdentifierStart<C> extends true ? ParseIdentifierPrimary<S> : ParseError : ParseError;
|
|
431
|
-
type ParseIdentifierPrimary<S extends string> = ParseIdentifier<TrimStart<S>> extends [infer Name extends string, infer Rest extends string] ? Name extends "" ? ParseError : ParseResult<ASTIdentifier<Name>, Rest> : ParseError;
|
|
432
|
-
type ParseStringLiteral<S extends string> = S extends `'${infer __}` ? {
|
|
433
|
-
rest: SkipSingleQuoteString<S>;
|
|
434
|
-
} : S extends `"${infer __}` ? {
|
|
435
|
-
rest: SkipDoubleQuoteString<S>;
|
|
436
|
-
} : S extends `\`${infer __}` ? {
|
|
437
|
-
rest: SkipTemplateString<S>;
|
|
438
|
-
} : never;
|
|
439
440
|
/** 解析表达式入口 */
|
|
440
441
|
type ParseExpression<S extends string> = ParseTernary<S> extends ParseResult<infer AST, infer Rest> ? TrimStart<Rest> extends "" ? AST : ASTUnknown : ASTUnknown;
|
|
442
|
+
//#endregion
|
|
443
|
+
//#region src/types/type-parser/type-inference.d.ts
|
|
441
444
|
/** 推导数组元素类型 */
|
|
442
445
|
type InferArrayElements<Elements extends unknown[], TypeMap, Result extends unknown[] = []> = Elements extends [infer First, ...infer Rest] ? InferArrayElements<Rest, TypeMap, [...Result, InferTypeFromAST<First, TypeMap>]> : Result;
|
|
443
446
|
/** 推导对象属性类型 */
|
|
@@ -456,25 +459,8 @@ type InferComputedMemberType<Obj> = Obj extends readonly (infer T)[] ? T : Obj e
|
|
|
456
459
|
} ? T : Obj extends Record<string, infer V> ? V : unknown;
|
|
457
460
|
/** 函数调用类型推导 */
|
|
458
461
|
type InferCallType<Callee> = Callee extends ((...args: any[]) => infer R) ? R : unknown;
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
Math: Math;
|
|
462
|
-
JSON: JSON;
|
|
463
|
-
Number: NumberConstructor;
|
|
464
|
-
String: StringConstructor;
|
|
465
|
-
Boolean: BooleanConstructor;
|
|
466
|
-
Array: ArrayConstructor;
|
|
467
|
-
Object: ObjectConstructor;
|
|
468
|
-
Date: DateConstructor;
|
|
469
|
-
RegExp: RegExpConstructor;
|
|
470
|
-
undefined: undefined;
|
|
471
|
-
NaN: number;
|
|
472
|
-
Infinity: number;
|
|
473
|
-
parseInt: typeof globalThis.parseInt;
|
|
474
|
-
parseFloat: typeof globalThis.parseFloat;
|
|
475
|
-
isNaN: typeof globalThis.isNaN;
|
|
476
|
-
isFinite: typeof globalThis.isFinite;
|
|
477
|
-
}
|
|
462
|
+
//#endregion
|
|
463
|
+
//#region src/types/type-parser/index.d.ts
|
|
478
464
|
/** 表达式验证结果 */
|
|
479
465
|
type ValidateExpression<Source extends string, TContext> = ExtractIdentifiers<Source> extends infer Ids extends string ? keyof TContext extends infer Keys extends string ? FindUndefinedIdentifiers<Ids, Keys> extends never ? true : {
|
|
480
466
|
error: "undefined_identifiers";
|
|
@@ -487,7 +473,7 @@ type ValidateExpression<Source extends string, TContext> = ExtractIdentifiers<So
|
|
|
487
473
|
/** 从表达式推导返回类型 */
|
|
488
474
|
type InferExpressionResult<Source extends string, TContext> = InferTypeFromAST<ParseExpression<Source>, ContextTypeMap<TContext>>;
|
|
489
475
|
//#endregion
|
|
490
|
-
//#region src/expr.d.ts
|
|
476
|
+
//#region src/api/expr.d.ts
|
|
491
477
|
/**
|
|
492
478
|
* 创建表达式
|
|
493
479
|
* 返回 Proxy Expression,可以继续链式调用
|
|
@@ -517,7 +503,7 @@ type InferExpressionResult<Source extends string, TContext> = InferTypeFromAST<P
|
|
|
517
503
|
*/
|
|
518
504
|
declare function expr<TContext extends Record<string, unknown>>(context: TContext): <TSource extends string>(source: ValidateExpression<TSource, TContext> extends never ? never : TSource) => Proxify<InferExpressionResult<TSource, TContext>>;
|
|
519
505
|
//#endregion
|
|
520
|
-
//#region src/lambda.d.ts
|
|
506
|
+
//#region src/api/lambda.d.ts
|
|
521
507
|
/**
|
|
522
508
|
* 创建类型安全的 lambda 表达式
|
|
523
509
|
*
|
|
@@ -538,7 +524,7 @@ declare function expr<TContext extends Record<string, unknown>>(context: TContex
|
|
|
538
524
|
*/
|
|
539
525
|
declare function lambda<Args extends unknown[], R>(builder: LambdaBuilder<Args, R>): Lambda<Args, R>;
|
|
540
526
|
//#endregion
|
|
541
|
-
//#region src/template.d.ts
|
|
527
|
+
//#region src/api/template.d.ts
|
|
542
528
|
/**
|
|
543
529
|
* Tagged template 函数,用于创建包含变量的字符串表达式
|
|
544
530
|
*
|
|
@@ -556,36 +542,7 @@ declare function lambda<Args extends unknown[], R>(builder: LambdaBuilder<Args,
|
|
|
556
542
|
*/
|
|
557
543
|
declare function t(strings: TemplateStringsArray, ...values: unknown[]): Proxify<string>;
|
|
558
544
|
//#endregion
|
|
559
|
-
//#region src/
|
|
560
|
-
/**
|
|
561
|
-
* 从变量映射推导值类型
|
|
562
|
-
* 例如: { x: Variable<number> } -> { x: number }
|
|
563
|
-
*/
|
|
564
|
-
type InferVariableValues<T extends Record<string, Variable<unknown>>> = { [K in keyof T]: T[K] extends Variable<infer U> ? U : never };
|
|
565
|
-
/**
|
|
566
|
-
* 编译并求值表达式
|
|
567
|
-
* 自动推导变量类型和返回类型
|
|
568
|
-
*
|
|
569
|
-
* @template TResult - 表达式求值结果类型
|
|
570
|
-
* @template TVars - 变量映射类型
|
|
571
|
-
* @param expr - 要编译的表达式
|
|
572
|
-
* @param variables - 变量定义映射
|
|
573
|
-
* @param values - 变量值映射
|
|
574
|
-
* @returns 表达式求值结果
|
|
575
|
-
*
|
|
576
|
-
* @example
|
|
577
|
-
* ```ts
|
|
578
|
-
* const callback = variable<(f: (x: number) => number) => number>();
|
|
579
|
-
* const result = compileAndEvaluate(
|
|
580
|
-
* myExpr,
|
|
581
|
-
* { callback },
|
|
582
|
-
* { callback: (fn) => fn(5) }
|
|
583
|
-
* );
|
|
584
|
-
* ```
|
|
585
|
-
*/
|
|
586
|
-
declare function compileAndEvaluate<TResult = unknown, TVars extends Record<string, Variable<unknown>> = Record<string, Variable<unknown>>>(expr: ExprValue<TResult>, variables: TVars, values: InferVariableValues<TVars>, options?: CompileOptions): UnproxyDeep<TResult>;
|
|
587
|
-
//#endregion
|
|
588
|
-
//#region src/variable.d.ts
|
|
545
|
+
//#region src/api/variable.d.ts
|
|
589
546
|
/**
|
|
590
547
|
* 创建一个类型化变量
|
|
591
548
|
* 返回 Proxy 对象,支持链式属性访问和方法调用
|
|
@@ -599,7 +556,7 @@ declare function compileAndEvaluate<TResult = unknown, TVars extends Record<stri
|
|
|
599
556
|
*/
|
|
600
557
|
declare function variable<T>(): Variable<T>;
|
|
601
558
|
//#endregion
|
|
602
|
-
//#region src/wrap.d.ts
|
|
559
|
+
//#region src/api/wrap.d.ts
|
|
603
560
|
/**
|
|
604
561
|
* 将静态值包装为 Proxy Expression
|
|
605
562
|
* 返回的 Proxy 可以像 Variable 一样调用方法和访问属性
|
|
@@ -626,5 +583,53 @@ declare function variable<T>(): Variable<T>;
|
|
|
626
583
|
*/
|
|
627
584
|
declare function wrap<T>(value: T): Proxify<T>;
|
|
628
585
|
//#endregion
|
|
629
|
-
|
|
586
|
+
//#region src/core/compile.d.ts
|
|
587
|
+
/**
|
|
588
|
+
* 编译选项
|
|
589
|
+
*/
|
|
590
|
+
interface CompileOptions {}
|
|
591
|
+
/**
|
|
592
|
+
* 将 Proxy Expression 编译为可序列化的 JSON 结构
|
|
593
|
+
*
|
|
594
|
+
* @template TResult - 表达式结果类型
|
|
595
|
+
* @param expression - Proxy Expression,或包含 Proxy 的对象/数组/原始值
|
|
596
|
+
* @param variables - 所有使用的变量定义
|
|
597
|
+
* @param options - 编译选项
|
|
598
|
+
* @returns 编译后的数据结构 [变量名列表, 表达式1, 表达式2, ...]
|
|
599
|
+
*
|
|
600
|
+
* @throws 如果传入无效的表达式或未定义的变量引用
|
|
601
|
+
*
|
|
602
|
+
* @example
|
|
603
|
+
* ```ts
|
|
604
|
+
* const x = variable<number>()
|
|
605
|
+
* const y = variable<number>()
|
|
606
|
+
* const sum = expr({ x, y })("x + y")
|
|
607
|
+
* const result = expr({ sum, x })("sum * x")
|
|
608
|
+
* const compiled = compile(result, { x, y })
|
|
609
|
+
* // => [["x", "y"], "($[0]+$[1])*$[0]"]
|
|
610
|
+
* ```
|
|
611
|
+
*/
|
|
612
|
+
declare function compile<TResult>(expression: ExprValue<TResult>, variables: Record<string, unknown>, _options?: CompileOptions): CompiledData;
|
|
613
|
+
//#endregion
|
|
614
|
+
//#region src/core/evaluate.d.ts
|
|
615
|
+
/**
|
|
616
|
+
* 执行编译后的表达式
|
|
617
|
+
*
|
|
618
|
+
* @template TResult - 表达式结果类型
|
|
619
|
+
* @param data - 编译后的数据结构 [变量名列表, 表达式1, 表达式2, ...]
|
|
620
|
+
* @param values - 变量值映射,按变量名提供值
|
|
621
|
+
* @returns 最后一个表达式的求值结果
|
|
622
|
+
*
|
|
623
|
+
* @throws 如果运行时类型验证失败或表达式执行出错
|
|
624
|
+
*
|
|
625
|
+
* @example
|
|
626
|
+
* ```ts
|
|
627
|
+
* const compiled = [["x", "y"], "$[0]+$[1]", "$[1]*2"]
|
|
628
|
+
* const result = evaluate<number>(compiled, { x: 2, y: 3 })
|
|
629
|
+
* // => 6 (3 * 2)
|
|
630
|
+
* ```
|
|
631
|
+
*/
|
|
632
|
+
declare function evaluate<TResult = unknown>(data: CompiledData, values: Record<string, unknown>): TResult;
|
|
633
|
+
//#endregion
|
|
634
|
+
export { type CompileOptions, type CompiledData, type CompiledExpression, type ExprValue, type FnNode, type InferLambdaArgs, type InferLambdaReturn, type Lambda, type LambdaBuilder, type Proxify, type ProxyExpression, type Variable, compile, evaluate, expr, lambda, t, variable, wrap };
|
|
630
635
|
//# sourceMappingURL=index.d.mts.map
|