Constraint check resolves an un-annotated accessor while its object literal is still being inferred
まだ誰も着手していません。
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 35/100
- issue の種類
- バグ
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- typescript
- 領域
- compilers
調査の方向性
The issue involves TypeScript's type inference and constraint checking in a recursive object literal with a getter. Start by examining the constraint in the array function and the Writeable mapped type. Look at the deferred type checking logic in the compiler, particularly around issue #64413. Run the provided code in the TypeScript playground to see the error, then trace through the type checker's handling of circular references and deferred nodes.
索引モデルが issue の本文から書いたものです。
説明
🔎 Search Terms
recursive object literal getter accessor constraint check circular "implicitly has return type" mapped type zod
🕗 Version & Regression Information
- This is the behavior in every version I tried, including
typescript@7.1.0-dev.20260918.1with #64311
⏯ Playground Link
No response
💻 Code
type output<T> = T extends { _zod: { output: any } } ? T["_zod"]["output"] : unknown;
type input<T> = T extends { _zod: { input: any } } ? T["_zod"]["input"] : unknown;
type NoUndefined<T> = T extends undefined ? never : T;
type Writeable<T> = { -readonly [P in keyof T]: T[P] };
type Prettify<T> = { [K in keyof T]: T[K] } & {};
interface $ZodTypeInternals<out O = unknown, out I = unknown> { def: unknown; output: O; input: I; optin?: "optional" | undefined; optout?: "optional" | undefined }
interface StandardProps<I, O> { readonly types?: { readonly input: I; readonly output: O } | undefined }
interface $ZodType<O = unknown, I = unknown, Internals extends $ZodTypeInternals<O, I> = $ZodTypeInternals<O, I>> {
_zod: Internals;
"~standard": StandardProps<input<this>, output<this>>;
}
interface ZodType<out Internals extends $ZodTypeInternals = $ZodTypeInternals> extends $ZodType<any, any, Internals> {
default(def: NoUndefined<output<this>>): ZodDefault<this>;
default(def: () => NoUndefined<output<this>>): ZodDefault<this>;
}
type Shape = Readonly<{ [k: string]: $ZodType }>;
type OptionalOut = { _zod: { optout: "optional" } };
type OptionalIn = { _zod: { optin: "optional" } };
type $InferObjectOutput<T extends Shape> = Prettify<
{ -readonly [k in keyof T as T[k] extends OptionalOut ? never : k]: T[k]["_zod"]["output"] } &
{ -readonly [k in keyof T as T[k] extends OptionalOut ? k : never]?: T[k]["_zod"]["output"] }
>;
type $InferObjectInput<T extends Shape> = Prettify<
{ -readonly [k in keyof T as T[k] extends OptionalIn ? never : k]: T[k]["_zod"]["input"] } &
{ -readonly [k in keyof T as T[k] extends OptionalIn ? k : never]?: T[k]["_zod"]["input"] }
>;
interface $ZodStringInternals extends $ZodTypeInternals { def: { type: "string" }; output: string; input: string }
interface ZodString extends ZodType<$ZodStringInternals> {}
declare function string(): ZodString;
interface $ZodObjectInternals<S extends Shape> extends $ZodTypeInternals { def: { type: "object"; shape: S }; output: $InferObjectOutput<S>; input: $InferObjectInput<S> }
interface ZodObject<S extends Shape> extends ZodType<$ZodObjectInternals<S>> { shape: S }
declare function object<T extends Shape>(shape: T): ZodObject<Writeable<T>>;
interface $ZodArrayInternals<T extends $ZodType> extends $ZodTypeInternals { def: { type: "array"; element: T }; output: output<T>[]; input: input<T>[] }
interface ZodArray<T extends $ZodType> extends ZodType<$ZodArrayInternals<T>> { element: T }
declare function array<T extends $ZodType>(element: T): ZodArray<T>;
interface $ZodDefaultInternals<T extends $ZodType> extends $ZodTypeInternals { def: { type: "default"; inner: T }; output: NoUndefined<output<T>>; input: input<T> | undefined; optin: "optional" }
interface ZodDefault<T extends $ZodType> extends ZodType<$ZodDefaultInternals<T>> {}
const Tree = object({
name: string(),
get children() {
return array(Tree).default([]);
},
});
🙁 Actual behavior
children is reported as circular, TS7023 on the getter and TS2615 in Writeable.
🙂 Expected behavior
The getter infers ZodDefault<ZodArray<typeof Tree>>, as it does when array's constraint omits output.
Additional information about the issue
The check of array's type argument against $ZodType compares _zod, whose output property instantiates Tree's inferred output type, and the mapped property of Writeable for children reads the getter while its return type is still being inferred. The same happens through the outer call when object constrains its shape to Readonly<{ [k: string]: $ZodType }>. Zod avoids both today by constraining its builders to a looser type that omits output. #64413 defers those checks until the file's deferred nodes have run.
- 主要言語
- Go
- スター
- 111k
- フォーク
- 14.4k
- 平均マージ
- 2日 3時間
- マージ済み PR(30日)
- 125
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
microsoft/TypeScript のほかの issue
-
Possible Improvement
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
microsoft/TypeScript#64278 · コメント 1 件 · リアクション 1 件 ·
-
Docs
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
microsoft/TypeScript#64118 · コメント 1 件 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
microsoft/TypeScript#64094 ·
-
Docs
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
microsoft/TypeScript#63959 · コメント 5 件 ·
-
Domain: lib.d.ts Help Wanted
難易度 1/5 1時間未満 初心者へのやさしさ 91/100
microsoft/TypeScript#63722 · コメント 4 件 · リアクション 1 件 ·
microsoft/TypeScript の issue をすべて見る
似ている issue
-
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
-
Bob Shell support オープンenhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
santhosh-tekuri/jsonschema#276 ·