Improving TypeScript Schema Inference and Type Constraints in Effect Library

Okay continuing on the above I came up with this https://effect.website/play/#f85207ef22c4. Was wondering how this could be improved. Should probably look into annotations etc I assume, but also wondering if there's a better way to type this. Both getting ride of the ts ignores but also constraining the schemas passed in to have a string as decoded type (just using Schema.Schema<string> etc made it lose inference on Literals without using as const on them

import { type Array, Schema } from "effect"

type EncodedBucketKey<Params extends Array.NonEmptyReadonlyArray<Schema.Any>> = Params extends [
  infer Head,
  ...infer Tail extends Array.NonEmptyReadonlyArray<Schema.Any>
] ? `${Schema.Schema.Encoded<Head> & string}/${EncodedBucketKey<Tail>}`
  : Schema.Schema.Encoded<Params[0]> & string

type DecodedBucketKey<Params extends Array.NonEmptyReadonlyArray<Schema.Any>> = {
  [K in keyof Params]: Schema.Schema.Type<Params[K]>
}

const BucketKey = <Params extends Array.NonEmptyReadonlyArray<Schema.Any>>(
  ...params: Params
): Schema.Schema<DecodedBucketKey<Params>, `/${EncodedBucketKey<Params>}`> => {
  // @ts-expect-error
  const Tuple = Schema.Tuple(...params)
  // @ts-expect-error
  return Schema.transform(Schema.String, Tuple, {
    strict: true,
    decode: (item) => item.split("/").slice(1),
    encode: (item) => "/" + item.join("/")
  })
}

const ListingId = Schema.UUID.pipe(Schema.brand("ListingId"))

const MyBucketKey = BucketKey(Schema.Literal("a"), ListingId)
// const MyBucketKey: Schema.Schema<["a", string & Brand<"ListingId">], `/a/${string}`, never>
Was this page helpful?