TheEdoRan / next-safe-action

Type safe and validated Server Actions in your Next.js project.
https://next-safe-action.dev
MIT License
2.29k stars 35 forks source link

support primitive-object-intersection types (branded primitive types) #277

Closed aleclofabbro closed 3 weeks ago

aleclofabbro commented 1 month ago

returnValidationErrors() typechecking fails when a property is a primitive-object-intersection type (typical case of branded type).

returnValidationErrors() refers to type SchemaErrors<S> for typings the purpose of type SchemaErrors<S> as is:

type SchemaErrors<S> = {
    [K in keyof S]?: S[K] extends object | null | undefined 
      ? Prettify<VEList & SchemaErrors<S[K]>> 
      : VEList;
} & {};

is to map S properties conditionally: if property S[K] is object | null | undefined maps to Prettify<VEList & SchemaErrors<S[K]>> else (property S[K] is primitive) maps to VEList

the issue arises when property S[K] is a branded primitive type. Branded primitive types are typically an intersection of a primitive with an object holding the brand (e.g. type email = string & { [k in brand_prop_type]: unique symbol })

type SchemaErrors<S> mapping condition considers branded-primitive-types as object, mapping them incorrectly, and finally leading to returnValidationErrors() type errors

Proposed changes

the issue is resolved by simply reversing the condition:

type SchemaErrors<S> = {
  [K in keyof S]?: S[K] extends number | string | boolean | bigint
    ? VEList
    : Prettify<VEList & SchemaErrors<S[K]>>;
} & {};

this way any primitive - even when intersected - is eagerly catched and properly managed, keeping logic unaltered

Related issue(s) or discussion(s)

This is an improvement of a previous PR https://github.com/TheEdoRan/next-safe-action/pull/273

re #


vercel[bot] commented 1 month ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
next-safe-action-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 26, 2024 9:34pm
vercel[bot] commented 1 month ago

@aleclofabbro is attempting to deploy a commit to the Edoardo Ranghieri's projects Team on Vercel.

A member of the Team first needs to authorize it.

aleclofabbro commented 1 month ago

HA! It crossed my mind the primitive union may need to contain symbol too ! S[K] extends number | string | boolean | bigint | symbol

TheEdoRan commented 1 month ago

@aleclofabbro seems good to me! If the union needs to include symbol too, please push a commit with that and then I'll merge the PR, after testing it. Thank you!

aleclofabbro commented 3 weeks ago

closed in favor of #284