#Union wrangling

1 messages ยท Page 1 of 1 (latest)

solid whaleBOT
#
m.a.t.t.t#0

Preview:```ts
import type {Token as MooToken} from "moo"

export type Token = Omit<MooToken, "toString">
type TypeInfo = {stub: true}

export enum NodeKind {
Program = "Program",
ExtractStmt = "ExtractStmt",
AssignmentStmt = "AssignmentStmt",
DeclImportStmt = "DeclImportStmt",
...```

uneven zenith
#

You'll have to add some more specific examples of the expected behavior

proud tiger
#

in the snippet i'm trying to process this type:

export type RequestExpr = {
  kind: NodeKind.RequestExpr
  method: Token
  url: Expr
  headers: ObjectLiteralExpr
  body?: Expr
}

Expr is the union, and ObjectLiteralExpr is a member of the union
Im able to keep ObjectLiteralExpr (headers) and remove the union (url)

however because body has ? its essentially Expr | undefined and i need to remove it (a la url) but its being kept

#

ie. type X becomes this:

type X = {
    kind: never;
    method: never;
    url: never;
    headers: ObjectLiteralExpr;
    body?: Expr;
}

but I need the last field to be body: never or body?: never - the goal is to drop any fields that refer to the union as a whole and not just a member of the union

#

ah ok i think i see your point about using infer V:

type CollectNode<T extends Node> = T extends T ? {
//   [K in keyof T]: FilterNarrow<T[K]>
//   [K in keyof T]: Expr extends FilterNarrow<T[K]> ? true : false
    [K in keyof T]: T[K] extends infer V ? Expr extends V ? true : false : never
} : never
#

ok cool that did the trick, thanks!
i do have some undefineds appearing where i would expect never... but will worry about that later

i wish there was a TS debugger that showed you where things were being distributed and how

uneven zenith
proud tiger
#

are there any TS debuggers? would really help to see how types ar ebeing evaluated in the same way we debug other languages

or the other thing is some kind of API to build up a type definition procedurally, ive seen some nice ones for regex before

uneven zenith
#

Nothing close to robust enough I'd consider using it

#

For now you're best off using certain tricks to e.g. return debugging values from your types in certain conditions so you can diagnose what is happening

proud tiger
#
type Node = Expr | Stmt

type FilterNarrow<T> = Expr extends T
  ? FilterNarrow<Exclude<T, Expr>>
  : T extends Stmt | TypeInfo
    ? never
    : T extends Expr
      ? T
      : T extends readonly(infer E)[]
        ? FilterNarrow<E>
        : T extends object
          ? Collect<T>
          : never


type Collect<T> = T extends T ? {
  [K in keyof T]: FilterNarrow<T[K]>
}[keyof T] : never

type NarrowExpr = Collect<Node>

might need some headache tablets now ๐Ÿ˜–

rose ocean
solid whaleBOT
#
type Collect<T> = {
    [K in keyof T]: [T[K]]
}

type Result = Collect<{ foo: string } | { bar: number }>
//   ^? - type Result = Collect<{
//       foo: string;
//   }> | Collect<{
//       bar: number;
//   }>
rose ocean
#

Also from a glance, not sure if it's intended to unwrap arrays.

proud tiger
#

that seems to work until i add [keyof T] after the object in Collect, to collect the values intoa union - then it seems to stop distributing