Skip to content

feat: Enhance FieldKeys and FieldType to support nested fields in Schema. - #25

Open
christophe-g wants to merge 2 commits into
fwal:mainfrom
christophe-g:feat-nested-key-type
Open

feat: Enhance FieldKeys and FieldType to support nested fields in Schema.#25
christophe-g wants to merge 2 commits into
fwal:mainfrom
christophe-g:feat-nested-key-type

Conversation

@christophe-g

Copy link
Copy Markdown
Contributor

This should close #18.

@fwal

fwal commented Mar 4, 2026

Copy link
Copy Markdown
Owner

Great! I'm looking into something similar for updates using Paths and Get from type-fest .

Could you also rebase-away me as co-author of d369085 😅

@christophe-g

Copy link
Copy Markdown
Contributor Author

@fwal - thanks.

You can close this PR if you plan to include type-fest - I won't be offended ; ).

For the time being, I have a couple of @ts-expect-error for queries with nested keys and I am ok with this for a couple of additional days / weeks.

Out of curiosity - plans for Effect 4 for this lib? Not asking for an ETA, just to know if it will be there at some stage. Cheers !

@fwal

fwal commented Mar 6, 2026

Copy link
Copy Markdown
Owner

Out of curiosity - plans for Effect 4 for this lib? Not asking for an ETA, just to know if it will be there at some stage. Cheers !

Not had time to dip my toes in just yet but will start work soon, thinking that an eventual 1.0 will run on Effect 4 🎉

@fwal

fwal commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Close/Reopen to trigger CI - long time, but let's get this merged 😅

@fwal fwal closed this Sep 9, 2026
@fwal fwal reopened this Sep 9, 2026
@fwal
fwal self-requested a review as a code owner September 9, 2026 13:57
@fwal fwal added the 🚀 feature A new feature or larger change label Sep 9, 2026
@greptile-apps

greptile-apps Bot commented Sep 9, 2026

Copy link
Copy Markdown

Greptile Summary

This PR extends Firestore query field-key and value-type utilities to support nested fields represented with dot notation.

  • Recursively derives nested field paths through FieldKeys.
  • Recursively resolves nested query value types through FieldType.

Confidence Score: 4/5

The nested field-value mapping should be corrected before merging because it accepts values belonging to sibling fields.

The new dotted-path branch ignores the inferred tail and feeds every nested key back into FieldType, weakening the type safety that the query APIs rely on.

Files Needing Attention: packages/effect-firebase/src/lib/firestore/query/query.ts

Important Files Changed

Filename Overview
packages/effect-firebase/src/lib/firestore/query/query.ts Adds nested field-path typing, but nested value resolution discards the requested suffix and returns a union of sibling field types.

Fix all with Greploop Fix All in Claude Code

Reviews (1): Last reviewed commit: "chore: revert indent spacing" | Re-trigger Greptile

? FieldType<T, K>
: K extends `${infer Head}.${infer Tail}`
? Head extends keyof S
? FieldType<S[Head], FieldKeys<S[Head]>>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Nested path tail is discarded

When querying a nested field whose siblings have different types, this branch passes every key below Head instead of the inferred Tail, so FieldType<S, "author.name"> becomes a sibling-type union and accepts invalid query values such as a number for a string field.

Suggested change
? FieldType<S[Head], FieldKeys<S[Head]>>
? FieldType<S[Head], Extract<Tail, FieldKeys<S[Head]>>>

Fix in Claude Code

@fwal

fwal commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Seems to cause a circular dependency in the examples

@christophe-g

Copy link
Copy Markdown
Contributor Author

Seems to cause a circular dependency in the examples

Hmm, I indeed have some exception (ExcludedTypesT) in my production code, was hoping it would not be necessary here:

type effectLiteralArray = readonly (string)[]
type DotPrefix<T extends string> = T extends "" ? "" : `.${T}`
type DocumentReference = {
  firestore: any
  path: string
  id: string
  parent: any
}
type OptionT = Option.Option<any>
type ExcludedTypesT = Date | ((...args: any[]) => any) | Array<any> | effectLiteralArray |
  DocumentReference | Stripe.Invoice | File | FileSchemaT | FirestoreSchema.Reference | OptionT
// typeof Schema.Type 
export type NestedKeys<T> = (
  T extends ExcludedTypesT ? "" :
  // branded primitives (e.g. Effect Schema.brand) extend their primitive
  T extends (string | number | bigint | boolean | symbol) ? "" :
  T extends object ?
  { [K in Exclude<keyof T, symbol>]: `${K}${DotPrefix<NestedKeys<T[K]>>}` }[Exclude<keyof T, symbol>]
  : "") extends infer D ? Extract<D, string> : never

export type NestedValue<T, Key extends string> = Key extends `${infer K}.${infer Rest}` ?
  K extends keyof T ? NestedValue<T[K], Rest> : never :
  Key extends keyof T ? T[Key] : never

@fwal

fwal commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Landing nested fields for updates in #83 if that's of any help 😅

@fwal

fwal commented Sep 10, 2026

Copy link
Copy Markdown
Owner

I took a stab on it in #84, hope you don't mind.

@christophe-g

christophe-g commented Sep 10, 2026 via email

Copy link
Copy Markdown
Contributor Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🚀 feature A new feature or larger change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nested keys are not inferred on queries

2 participants