From 1cfa1f6a49d1f2e3e512a74ab611c82c5c2db773 Mon Sep 17 00:00:00 2001
From: Paul Visscher
Date: Sun, 19 May 2024 22:44:53 +0200
Subject: [PATCH] refactor: remove tree type inferrence
---
src/engine/operator.ts | 27 ++++++------
src/engine/policy.ts | 24 ++++-------
src/engine/types.spec.ts | 4 +-
src/engine/types.ts | 17 +++++---
src/expressions/boolean.spec.ts | 57 ++++++++++++++++++-------
src/expressions/boolean.ts | 10 ++---
src/expressions/higher-order-fn.spec.ts | 24 +++++++----
src/expressions/higher-order-fn.ts | 19 +++++++--
src/expressions/input.ts | 26 +++++------
src/expressions/logic.spec.ts | 28 +++++++++---
src/expressions/logic.ts | 4 +-
src/expressions/number-array.spec.ts | 20 ++++++---
src/expressions/number.spec.ts | 42 +++++++++++-------
src/expressions/string.spec.ts | 11 +++--
test/policies.spec.ts | 5 ++-
15 files changed, 198 insertions(+), 120 deletions(-)
diff --git a/src/engine/operator.ts b/src/engine/operator.ts
index bcfd72a..11a091a 100644
--- a/src/engine/operator.ts
+++ b/src/engine/operator.ts
@@ -1,9 +1,9 @@
+import { inspect } from 'node:util'
+import type { JSONExpr } from '../json/jsonexpr.type.js'
import type { AsExpression, DefinitionType, Expression, ValueExpression } from './types.js'
import { fromLiteral } from './types.js'
-import type { JSONExpr } from '../json/jsonexpr.type.js'
-
-import { inspect } from 'node:util'
+export type FactsFomExprs = T extends { facts: infer U } ? U : never
// biome-ignore lint/suspicious/noExplicitAny: any is necessary for the operator function
export interface Operator {
@@ -11,8 +11,13 @@ export interface Operator {
operator: Op
| I[K] }>(
...exprs: Exprs
+ ): ValueExpression<
+ O,
+ { [K in keyof I]: AsExpression },
+ FactsFomExprs,
// biome-ignore lint/suspicious/noExplicitAny: any is necessary for the operator function
- ): ValueExpression }, Extract>>
+ Extract>
+ >
}
export function operator({
@@ -25,10 +30,7 @@ export function operator({
symbol: string
}): Operator {
return Object.assign(
- | I[K] }>(
- ...exprs: Exprs
- // biome-ignore lint/suspicious/noExplicitAny: any is necessary for the operator function
- ): ValueExpression }, Extract>> => {
+ | I[K] }>(...exprs: Exprs) => {
const xs = exprs.map((x) => fromLiteral(x as I[number]))
return {
fn,
@@ -39,16 +41,11 @@ export function operator({
[inspect.custom]() {
return `${symbol}(${xs.map((x) => x[inspect.custom]?.() ?? '').join(', ')})`
},
- } as unknown as ValueExpression<
- O,
- { [K in keyof I]: AsExpression },
- // biome-ignore lint/suspicious/noExplicitAny: any is necessary for the operator function
- Extract>
- >
+ }
},
{
symbol,
operator,
},
- )
+ ) as unknown as Operator
}
diff --git a/src/engine/policy.ts b/src/engine/policy.ts
index febd67e..0e068f2 100644
--- a/src/engine/policy.ts
+++ b/src/engine/policy.ts
@@ -1,6 +1,7 @@
import { collect, stack } from '@skyleague/axioms'
-import type { Simplify, UnionToIntersection } from '@skyleague/axioms/types'
+import type { IsEmptyObject, Simplify } from '@skyleague/axioms/types'
import { version } from '../../package.json'
+import type { FactsFomExprs } from './operator.js'
import type { Expression, ExpressionReturnType } from './types.js'
export class EvaluationContext {
@@ -73,23 +74,18 @@ function* collapseExpression(root: Expression[], seen = new WeakSet()) {
type InferFactName = Expr extends { name: string } ? Expr['name'] : k
-type FilterFactExpressions, k extends keyof Facts> = Facts[k] extends {
+type FilterFactExpressions = Facts[K] extends {
_type: 'fact'
}
- ? InferFactName
+ ? InferFactName
: never
-type CollapseTreeToArray = T extends { dependsOn: (infer U)[] } ? T | CollapseTreeToArray : T
-type _InputFromExpressions> = Simplify<{
- [k in keyof Facts as FilterFactExpressions]: ExpressionReturnType
+type _InputFromExpressions = Simplify<{
+ [K in keyof Facts as FilterFactExpressions]: ExpressionReturnType
}>
-type NamedUnionToRecord = T extends { name: infer Name } ? (Name extends PropertyKey ? { [k in Name]: T } : never) : never
-
+type _FactsFomExprs = Facts extends unknown[] ? Facts[number] : Facts
export type InputFromExpressions> = Simplify<
- _InputFromExpressions &
- _InputFromExpressions<
- UnionToIntersection ? CollapseTreeToArray : never>>
- >
+ _InputFromExpressions & _InputFromExpressions<{ [K in keyof Facts]: _FactsFomExprs> }>
>
export type OutputFromFacts> = Simplify<{
@@ -97,13 +93,12 @@ export type OutputFromFacts> = Simplify<{
}>
export interface Policy {
- evaluate: [I] extends [never] ? () => { input: I; output: O } : (x: I) => { input: I; output: O }
+ evaluate: IsEmptyObject extends true ? () => { input: I; output: O } : (x: I) => { input: I; output: O }
expr: () => unknown
}
export function $policy>(
expressions: Facts,
- // @ts-ignore
): Policy, OutputFromFacts> {
const facts = Object.entries(expressions).map(([name, e]) => {
if (e.name === undefined) {
@@ -122,7 +117,6 @@ export function $policy>(
const properties = Object.fromEntries(inputNodes.map((e) => [e.name, e.expr('definition')]))
const outputExpression = Object.fromEntries(outputNodes.map((f) => [f.name, f.expr('expression')]))
return {
- // @ts-ignore
evaluate: ((input: Record) => {
const ctx = new EvaluationContext(input)
diff --git a/src/engine/types.spec.ts b/src/engine/types.spec.ts
index d7d6d81..59db747 100644
--- a/src/engine/types.spec.ts
+++ b/src/engine/types.spec.ts
@@ -23,10 +23,10 @@ describe('fromLiteral', () => {
const fact = $fact(Arithmetic, 'input')
const fa = fromLiteral($from(fact, '$.a'))
const _fa_: Expression = fa
- expectTypeOf(fa).toEqualTypeOf]>>()
+ expectTypeOf(fa).toEqualTypeOf>>()
const fb = fromLiteral($from(fact, '$.b'))
const _fb_: Expression = fb
- expectTypeOf(fb).toEqualTypeOf]>>()
+ expectTypeOf(fb).toEqualTypeOf>>()
type val = ['1', '2']
const _test_multiple = {} as { [K in keyof val]: AsExpression }
diff --git a/src/engine/types.ts b/src/engine/types.ts
index fce02c3..c284b0d 100644
--- a/src/engine/types.ts
+++ b/src/engine/types.ts
@@ -1,6 +1,6 @@
import type { EvaluationContext } from './policy.js'
-import { $literal } from '../expressions/input.js'
+import { $literal, type Fact } from '../expressions/input.js'
import type {
BooleanArrExpr,
BooleanExpr,
@@ -40,6 +40,7 @@ export interface Expression O
expr: (definition: DefinitionType) => Expr
[inspect.custom]?(): string
@@ -50,20 +51,23 @@ export type ExpressionReturnType = E extends Pick ? ReturnT
// biome-ignore lint/suspicious/noExplicitAny: this is needed for greedy matching
export interface LiteralExpression> extends Expression {
dependsOn: []
+ // facts: []
_type: 'literal'
}
-export interface FactExpression> extends Expression {
+// biome-ignore lint/suspicious/noExplicitAny: this is needed for greedy matching
+export interface FactExpression> extends Expression {
_type: 'fact'
}
export interface InputExpression<
O,
I,
- DependsOn extends Expression[],
+ F extends Fact,
Expr extends JSONExpr | ValueItemExpr = InferExpressionType,
> extends Expression {
- dependsOn: DependsOn
+ dependsOn: [F]
+ facts: [F]
_type: 'value' | 'literal'
}
@@ -71,9 +75,10 @@ export type InputFromExpressions = {
[k in keyof Expr]: ExpressionReturnType
}
-export interface ValueExpression>
+export interface ValueExpression>
extends Expression, Expr> {
- dependsOn: DependsOn
+ // dependsOn: DependsOn
+ facts: Facts //extends FactExpression ? [Facts] : never
_type?: 'value'
}
diff --git a/src/expressions/boolean.spec.ts b/src/expressions/boolean.spec.ts
index 84824da..d7cec74 100644
--- a/src/expressions/boolean.spec.ts
+++ b/src/expressions/boolean.spec.ts
@@ -90,14 +90,20 @@ describe('startsWith', () => {
const x1 = $startsWith('1', '2')
expectTypeOf(x1).toEqualTypeOf<
- ValueExpression, LiteralExpression<'2', StringExpr>], StartsWithExpr>
+ ValueExpression<
+ boolean,
+ [LiteralExpression<'1', StringExpr>, LiteralExpression<'2', StringExpr>],
+ never,
+ StartsWithExpr
+ >
>()
const x2 = $startsWith($from(fact, '$.a'), '2')
expectTypeOf(x2).toEqualTypeOf<
ValueExpression<
boolean,
- [From]>, LiteralExpression<'2', StringExpr>],
+ [str: From>, searchString: LiteralExpression<'2', StringExpr>],
+ [Fact],
StartsWithExpr
>
>()
@@ -106,7 +112,8 @@ describe('startsWith', () => {
expectTypeOf(x3).toEqualTypeOf<
ValueExpression<
boolean,
- [LiteralExpression<'2', StringExpr>, From]>],
+ [str: LiteralExpression<'2', StringExpr>, searchString: From>],
+ [Fact],
StartsWithExpr
>
>()
@@ -190,14 +197,20 @@ describe('endsWith', () => {
const x1 = $endsWith('1', '2')
expectTypeOf(x1).toEqualTypeOf<
- ValueExpression, LiteralExpression<'2', StringExpr>], EndsWithExpr>
+ ValueExpression<
+ boolean,
+ [str: LiteralExpression<'1', StringExpr>, searchString: LiteralExpression<'2', StringExpr>],
+ never,
+ EndsWithExpr
+ >
>()
const x2 = $endsWith($from(fact, '$.a'), '2')
expectTypeOf(x2).toEqualTypeOf<
ValueExpression<
boolean,
- [From]>, LiteralExpression<'2', StringExpr>],
+ [str: From>, searchString: LiteralExpression<'2', StringExpr>],
+ [Fact],
EndsWithExpr
>
>()
@@ -206,7 +219,8 @@ describe('endsWith', () => {
expectTypeOf(x3).toEqualTypeOf<
ValueExpression<
boolean,
- [LiteralExpression<'2', StringExpr>, From]>],
+ [str: LiteralExpression<'2', StringExpr>, searchString: From>],
+ [Fact],
EndsWithExpr
>
>()
@@ -290,14 +304,20 @@ describe('includes', () => {
const x1 = $includes('1', '2')
expectTypeOf(x1).toEqualTypeOf<
- ValueExpression, LiteralExpression<'2', StringExpr>], IncludesExpr>
+ ValueExpression<
+ boolean,
+ [LiteralExpression<'1', StringExpr>, LiteralExpression<'2', StringExpr>],
+ never,
+ IncludesExpr
+ >
>()
const x2 = $includes($from(fact, '$.a'), '2')
expectTypeOf(x2).toEqualTypeOf<
ValueExpression<
boolean,
- [From]>, LiteralExpression<'2', StringExpr>],
+ [str: From>, searchString: LiteralExpression<'2', StringExpr>],
+ [Fact],
IncludesExpr
>
>()
@@ -306,7 +326,8 @@ describe('includes', () => {
expectTypeOf(x3).toEqualTypeOf<
ValueExpression<
boolean,
- [LiteralExpression<'2', StringExpr>, From]>],
+ [str: LiteralExpression<'2', StringExpr>, searchString: From>],
+ [Fact],
IncludesExpr
>
>()
@@ -413,7 +434,9 @@ describe('all', () => {
const fact = $fact(LogicObj, 'input')
const x1 = $all([1, 2], (x) => $equal(x, 1))
- expectTypeOf(x1).toEqualTypeOf], BooleanExpr>>()
+ expectTypeOf(x1).toEqualTypeOf<
+ ValueExpression], never, BooleanExpr>
+ >()
const a = $from(fact, '$.d')
const x2 = $all(a, (x) => $equal(x, 1))
@@ -427,9 +450,10 @@ describe('all', () => {
a: boolean
b: boolean
}[],
- [Fact]
+ Fact
>,
],
+ [Fact],
BooleanExpr
>
>()
@@ -437,7 +461,7 @@ describe('all', () => {
const ba = $from(fact, '$.b..a')
const x3 = $all(ba, (x) => $equal(x, 1))
expectTypeOf(x3).toEqualTypeOf<
- ValueExpression]>], BooleanExpr>
+ ValueExpression>], [Fact], BooleanExpr>
>()
})
})
@@ -542,7 +566,9 @@ describe('any', () => {
const fact = $fact(LogicObj, 'input')
const x1 = $any([1, 2], (x) => $equal(x, 1))
- expectTypeOf(x1).toEqualTypeOf], BooleanExpr>>()
+ expectTypeOf(x1).toEqualTypeOf<
+ ValueExpression], never, BooleanExpr>
+ >()
const a = $from(fact, '$.d')
const x2 = $any(a, (x) => $equal(x, 1))
@@ -556,9 +582,10 @@ describe('any', () => {
a: boolean
b: boolean
}[],
- [Fact]
+ Fact
>,
],
+ [Fact],
BooleanExpr
>
>()
@@ -566,7 +593,7 @@ describe('any', () => {
const ba = $from(fact, '$.b..a')
const x3 = $any(ba, (x) => $equal(x, 1))
expectTypeOf(x3).toEqualTypeOf<
- ValueExpression]>], BooleanExpr>
+ ValueExpression>], [Fact], BooleanExpr>
>()
})
})
diff --git a/src/expressions/boolean.ts b/src/expressions/boolean.ts
index d6a6a9d..07de8eb 100644
--- a/src/expressions/boolean.ts
+++ b/src/expressions/boolean.ts
@@ -1,6 +1,6 @@
import { $value, type ValueItem } from './higher-order-fn.js'
-import { operator } from '../engine/operator.js'
+import { type FactsFomExprs, operator } from '../engine/operator.js'
import {
type AsExpression,
type Expression,
@@ -44,7 +44,7 @@ export const $all = Object.assign(
>(
xs: Expr,
predicate: (value: ValueItem>) => Expression,
- ): ValueExpression]> => {
+ ): ValueExpression], FactsFomExprs> => {
const _xs = fromLiteral(xs)
const _value = $value>()
const _transform = predicate(_value)
@@ -59,7 +59,7 @@ export const $all = Object.assign(
[inspect.custom]() {
return `$all(${_xs[inspect.custom]?.() ?? ''}, (x) => ${_transform[inspect.custom]?.() ?? ''})`
},
- } as ValueExpression]>
+ } as ValueExpression], FactsFomExprs>
},
// biome-ignore lint/suspicious/noExplicitAny: this is needed for greedy matching
{ operator: 'all', symbol: '$all', parse: (xs: any, predicate: any) => $all(xs, () => predicate) } as const,
@@ -70,7 +70,7 @@ export const $any = Object.assign(
>(
xs: Expr,
predicate: (value: ValueItem>) => Expression,
- ): ValueExpression]> => {
+ ): ValueExpression], FactsFomExprs> => {
const _xs = fromLiteral(xs)
const _value = $value>()
const _transform = predicate(_value)
@@ -85,7 +85,7 @@ export const $any = Object.assign(
[inspect.custom]() {
return `$any(${_xs[inspect.custom]?.() ?? ''}, (x) => ${_transform[inspect.custom]?.() ?? ''})`
},
- } as ValueExpression]>
+ } as ValueExpression], FactsFomExprs>
},
// biome-ignore lint/suspicious/noExplicitAny: this is needed for greedy matching
{ operator: 'any', symbol: '$any', parse: (xs: any, predicate: any) => $any(xs, () => predicate) } as const,
diff --git a/src/expressions/higher-order-fn.spec.ts b/src/expressions/higher-order-fn.spec.ts
index e21b573..b640bae 100644
--- a/src/expressions/higher-order-fn.spec.ts
+++ b/src/expressions/higher-order-fn.spec.ts
@@ -181,20 +181,26 @@ describe('map', () => {
const fact = $fact(MathFn, 'input')
const x1 = $map([1, 2], (x) => x)
- expectTypeOf(x1).toEqualTypeOf], NumberExpr>>()
+ expectTypeOf(x1).toEqualTypeOf<
+ ValueExpression], never, NumberExpr>
+ >()
const a = $from(fact, '$.a')
const x2 = $map(a, (x) => x)
- expectTypeOf(x2).toEqualTypeOf]>], NumberExpr>>()
+ expectTypeOf(x2).toEqualTypeOf<
+ ValueExpression>], [Fact], NumberExpr>
+ >()
const ba = $from(fact, '$.b..a')
const x3 = $map(ba, (x) => x)
- expectTypeOf(x3).toEqualTypeOf]>], NumberExpr>>()
+ expectTypeOf(x3).toEqualTypeOf<
+ ValueExpression>], [Fact], NumberExpr>
+ >()
const b = $from(fact, '$.b')
const x4 = $map(b, (x) => x('$.a'))
expectTypeOf(x4).toEqualTypeOf<
- ValueExpression]>], NumberExpr>
+ ValueExpression>], [Fact], NumberExpr>
>()
})
})
@@ -285,24 +291,26 @@ describe('filter', () => {
const fact = $fact(MathFn, 'input')
const x1 = $filter([1, 2], (x) => $equal(x, 1))
- expectTypeOf(x1).toEqualTypeOf], NumberArrExpr>>()
+ expectTypeOf(x1).toEqualTypeOf<
+ ValueExpression], never, NumberArrExpr>
+ >()
const a = $from(fact, '$.a')
const x2 = $filter(a, (x) => $equal(x, 1))
expectTypeOf(x2).toEqualTypeOf<
- ValueExpression]>], NumberArrExpr>
+ ValueExpression>], [Fact], NumberArrExpr>
>()
const ba = $from(fact, '$.b..a')
const x3 = $filter(ba, (x) => $equal(x, 1))
expectTypeOf(x3).toEqualTypeOf<
- ValueExpression]>], NumberArrExpr>
+ ValueExpression>], [Fact], NumberArrExpr>
>()
const b = $from(fact, '$.b')
const x4 = $filter(b, (x) => $equal(1, x('$.a')))
expectTypeOf(x4).toEqualTypeOf<
- ValueExpression]>], JSONExpr>
+ ValueExpression>], [Fact], JSONExpr>
>()
})
})
diff --git a/src/expressions/higher-order-fn.ts b/src/expressions/higher-order-fn.ts
index 9c138fe..f1ea816 100644
--- a/src/expressions/higher-order-fn.ts
+++ b/src/expressions/higher-order-fn.ts
@@ -1,3 +1,4 @@
+import type { FactsFomExprs } from '../engine/operator.js'
import type { EvaluationContext } from '../engine/policy.js'
import {
type AsExpression,
@@ -16,7 +17,7 @@ import { JSONPath, type JSONPathValue } from '@skyleague/jsonpath'
import { inspect } from 'node:util'
// biome-ignore lint/suspicious/noExplicitAny: this is needed for greedy matching
-export interface Value extends InputExpression {
+export interface Value extends InputExpression {
_type: 'value'
}
function value(path?: P): P extends string ? Value> : Value {
@@ -62,7 +63,12 @@ export const $map = Object.assign(
, Expr extends LiteralOr>(
xs: Expr,
transform: (value: ValueItem>) => AsExpression,
- ): ValueExpression[], [AsExpression], InferExpressionType>> => {
+ ): ValueExpression<
+ ExpressionTypeOfLiteral[],
+ [AsExpression],
+ FactsFomExprs,
+ InferExpressionType>
+ > => {
const _xs = fromLiteral(xs)
const _value = $value>()
const _transform = transform(_value)
@@ -77,7 +83,12 @@ export const $map = Object.assign(
[inspect.custom]() {
return `$map(${_xs[inspect.custom]?.() ?? ''}, (x) => ${_transform[inspect.custom]?.() ?? ''})`
},
- } as ValueExpression[], [AsExpression], InferExpressionType>>
+ } as ValueExpression<
+ ExpressionTypeOfLiteral[],
+ [AsExpression],
+ FactsFomExprs,
+ InferExpressionType>
+ >
},
// biome-ignore lint/suspicious/noExplicitAny: this is needed for greedy matching
{ operator: 'map', symbol: '$map', parse: (xs: any, transform: any) => $map(xs, () => transform) } as const,
@@ -91,6 +102,7 @@ export const $filter = Object.assign(
): ValueExpression<
ExpressionTypeOfLiteral,
[AsExpression],
+ FactsFomExprs,
InferExpressionType>
> => {
const _xs = fromLiteral(xs)
@@ -110,6 +122,7 @@ export const $filter = Object.assign(
} as ValueExpression<
ExpressionTypeOfLiteral,
[AsExpression],
+ FactsFomExprs,
InferExpressionType>
>
},
diff --git a/src/expressions/input.ts b/src/expressions/input.ts
index d11c9f8..41d130f 100644
--- a/src/expressions/input.ts
+++ b/src/expressions/input.ts
@@ -1,11 +1,4 @@
-import type {
- DefinitionType,
- Expression,
- FactExpression,
- InferExpressionType,
- InputExpression,
- LiteralExpression,
-} from '../engine/types.js'
+import type { DefinitionType, FactExpression, InferExpressionType, InputExpression, LiteralExpression } from '../engine/types.js'
import type { FromExpr } from '../json/jsonexpr.type.js'
import { JSONPath, type JSONPathValue } from '@skyleague/jsonpath'
@@ -13,7 +6,8 @@ import type { Schema } from '@skyleague/therefore'
import { inspect } from 'node:util'
-export interface Fact extends FactExpression {
+// biome-ignore lint/suspicious/noExplicitAny: this is needed for greedy matching
+export interface Fact extends FactExpression {
name: Name
dependsOn: []
_type: 'fact'
@@ -34,32 +28,32 @@ export function $fact(schema: Pick, 'schema' |
},
}
}
-export interface From extends InputExpression {
+export interface From extends InputExpression {
_type: 'value'
}
-export function $from(fact: Fact): From, [Fact]>
+export function $from(fact: Fact): From, Fact>
export function $from(
fact: Fact,
path: P,
-): From, [Fact]>
+): From, Fact>
export function $from(
fact: Fact,
path: P = '$' as P,
-): From, [Fact]> {
+): From, Fact> {
return {
_type: 'value',
dependsOn: [fact],
fn: ((_: unknown, ctx: { input: Record }) => JSONPath.get(ctx.input[fact.name], path)) as From<
T,
JSONPathValue,
- [Fact]
+ Fact
>['fn'],
- expr: (_definition) => ({ from: [fact.name, path.toString()] as const }),
+ expr: () => ({ from: [fact.name, path.toString()] as const }),
[inspect.custom]() {
return `$from(${fact[inspect.custom]?.() ?? `"${fact.name}"`}${path === '$' ? '' : `, "${path}"`})`
},
- }
+ } as unknown as From, Fact>
}
export function $literal(x: O): LiteralExpression {
diff --git a/src/expressions/logic.spec.ts b/src/expressions/logic.spec.ts
index 38b330e..26624d9 100644
--- a/src/expressions/logic.spec.ts
+++ b/src/expressions/logic.spec.ts
@@ -76,6 +76,7 @@ describe('if', () => {
LiteralExpression,
LiteralExpression,
],
+ never,
IfExpr
>
>()
@@ -89,6 +90,7 @@ describe('if', () => {
LiteralExpression,
LiteralExpression,
],
+ never,
IfExpr
>
>()
@@ -154,14 +156,20 @@ describe('and', () => {
const x1 = $and(false, true, false)
expectTypeOf(x1).toEqualTypeOf<
- ValueExpression | LiteralExpression)[], AndExpr>
+ ValueExpression<
+ boolean,
+ (LiteralExpression | LiteralExpression)[],
+ never,
+ AndExpr
+ >
>()
const x2 = $and($from(fact, '$.c'), true)
expectTypeOf(x2).toEqualTypeOf<
ValueExpression<
boolean,
- (LiteralExpression | From]>)[],
+ (LiteralExpression | From>)[],
+ [Fact],
AndExpr
>
>()
@@ -170,7 +178,8 @@ describe('and', () => {
expectTypeOf(x3).toEqualTypeOf<
ValueExpression<
boolean,
- (LiteralExpression | From]>)[],
+ (From> | LiteralExpression)[],
+ [Fact],
AndExpr
>
>()
@@ -236,14 +245,20 @@ describe('or', () => {
const x1 = $or(false, true, false)
expectTypeOf(x1).toEqualTypeOf<
- ValueExpression | LiteralExpression)[], OrExpr>
+ ValueExpression<
+ boolean,
+ (LiteralExpression | LiteralExpression)[],
+ never,
+ OrExpr
+ >
>()
const x2 = $or($from(fact, '$.c'), true)
expectTypeOf(x2).toEqualTypeOf<
ValueExpression<
boolean,
- (LiteralExpression | From]>)[],
+ (From> | LiteralExpression)[],
+ [Fact],
OrExpr
>
>()
@@ -252,7 +267,8 @@ describe('or', () => {
expectTypeOf(x3).toEqualTypeOf<
ValueExpression<
boolean,
- (LiteralExpression