edgedb-js icon indicating copy to clipboard operation
edgedb-js copied to clipboard

Type incorrect for `union` operation on set with array properties

Open nerdoza opened this issue 7 months ago • 2 comments

Code The code causing the error.

const PersonIdentifierParams = {
  identifier: e.str,
  tokenizedName: e.array(e.str),
}

const agentIdentifiers = e.for(
  e.op(
    'distinct',
    e.op(
      e.op(
        e.op(
          e.array_unpack(params.feeTransactions).agentIdentifier,
          'union',
          e.array_unpack(params.paymentTransactions).agentIdentifier,
        ),
        'union',
        e.array_unpack(params.chargebackTransactions).agentIdentifier,
      ),
      'union',
      e.array_unpack(params.holdTransactions).agentIdentifier,
    ),
  ),
  agentIdentifierParams => e.op(
    e.assert_single(
      e.select(e.comp.AgentIdentifier, agentIdentifier => ({
        filter: e.op(
          e.op(
            e.op(agentIdentifier.tokenizedName, '?=', normalizeTupleArrayOp(agentIdentifierParams.tokenizedName)),
            'and',
            e.op(agentIdentifier.identifier, '?=', normalizeTupleStringOp(agentIdentifierParams.identifier)),
          ),
          'and',
          agentIdentifier.owner.isSelf,
        ),
      })),
    ),
    '??',
    e.insert(e.comp.AgentIdentifier, {
      identifier: normalizeTupleStringOp(agentIdentifierParams.identifier),
      owner: e.core.global.currentUser,
      tokenizedName: normalizeTupleArrayOp(agentIdentifierParams.tokenizedName),
    }),
  ),
)

Error or desired behavior

The expectation from the union of the param e.array(e.str) type be the same type, but for some reason it returns a type never.

Versions (please complete the following information):

  • OS:
  • EdgeDB version (e.g. 2.0): 6.4+4e5cdad
  • EdgeDB CLI version (e.g. 2.0): Gel CLI 7.3.0-dev.1347+7e5a953
  • edgedb-js version (e.g. 0.20.10;): [email protected]
  • @edgedb/generate version (e.g. 0.0.7;): @gel/[email protected]
  • TypeScript version: 5.7.3
  • Node/Deno version: v22.13.1

nerdoza avatar May 05 '25 16:05 nerdoza

Can you point out exactly where this is giving you never in your example? Technically speaking you cannot "union an array", only set has a definition for union, but I think that's just a semantic point. I'm not able to really mentally parse your example since it includes so much that isn't defined in your provided code (like the params here).

scotttrinh avatar May 05 '25 17:05 scotttrinh

The agentIdentifier is an alias of the PersonIdentifierParams param declared at the top of the code example, and is a common property on several param types.

The tokenizedName property is the array of strings mentioned.

So the result of the union of the agentIdentifier types from all the various params should result in a set of agentIdentifiers with a type of PersonIdentifierParams.

The type error is coming the first time I attempt to reference the tokenizedName property on the union set (agentIdentifiers).

Here's a screen shot and the full error for additional context:

Image

Type Error

Argument of type '$expr_TuplePath<never, Cardinality.One>' is not assignable to parameter of type '$expr_TuplePath<ArrayType<scalarTypeWithConstructor<$str, never>, "array<std::str>">, Cardinality.One>'.
  Type '$expr_TuplePath<never, Cardinality.One>' is not assignable to type 'ExpressionMethods<{ __element__: ArrayType<scalarTypeWithConstructor<$str, never>, "array<std::str>">; __cardinality__: Cardinality.One; }>'.
    The types returned by 'assert_single()' are incompatible between these types.
      Type 'assert_single<never, Cardinality.AtMostOne>' is not assignable to type 'assert_single<ArrayType<scalarTypeWithConstructor<$str, never>, "array<std::str>">, Cardinality.AtMostOne>'.
        Type 'assert_single<never, Cardinality.AtMostOne>' is not assignable to type '{ [index: number]: $expr_Operator<ScalarType<"std::str", string, string, string>, Cardinality.AtMostOne>; [slice: `${number}:${number}`]: $expr_Operator<ArrayType<scalarTypeWithConstructor<$str, never>, "array<std::str>">, Cardinality.AtMostOne>; [slice: `${number}:`]: $expr_Operator<...>; [slice: `:${number}`]: $ex...'.
          The types returned by 'index(...)' are incompatible between these types.
            Type '$expr_Operator<BaseType, any>' is not assignable to type '$expr_Operator<ScalarType<"std::str", string, string, string>, any>'.
              Type '$expr_Operator<BaseType, any>' is not assignable to type '{ __element__: ScalarType<"std::str", string, string, string>; __cardinality__: any; __kind__: ExpressionKind.Operator; __name__: string; __opkind__: OperatorKind; __args__: TypeSet<...>[]; }'.
                Types of property '__element__' are incompatible.
                  Type 'BaseType' is missing the following properties from type 'ScalarType<"std::str", string, string, string>': __tstype__, __tsargtype__, __tsconsttype__ts(2345)

nerdoza avatar May 05 '25 21:05 nerdoza