Skip to content

Support spread in recursive object inference #64531

Description

🔎 Search Terms

recursive object literal getter accessor spread "implicitly has type 'any'" 64311

🕗 Version & Regression Information

⏯ Playground Link

No response

💻 Code

interface Schema<O> { readonly out: O }
type Shape = Record<string, Schema<any>>;
declare function object<S extends Shape>(shape: S): Schema<{ [K in keyof S]: S[K]["out"] }>;
declare function array<T extends Schema<any>>(el: T): Schema<T["out"][]>;
declare function string(): Schema<string>;

// works since #64311
const A = object({
  name: string(),
  get children() { return array(A); },
});

// fails
const base = { name: string() };
const B = object({
  ...base,
  get children() { return array(B); },
});

🙁 Actual behavior

B is any, with TS7022 on B and TS7023 on children. A is the same declaration without the spread and infers Schema<{ name: string; readonly children: ...[] }>.

🙂 Expected behavior

B infers the same type as A.

Additional information about the issue

Spreading a shape is how Zod's docs extend an object schema, so right now a schema can't be both extended and recursive:

const Node = z.object({
  ...Base.shape,
  get children() { return z.array(Node); },
});

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Possible ImprovementThe current behavior isn't wrong, but it's possible to see that it might be better in some cases

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions