Constraint check resolves an un-annotated accessor while its object literal is still being inferred
還沒有人認領這個 Issue。
評估
- 難度
- 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 小時
- 30 天內合併 PR
- 125
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
microsoft/TypeScript 的其他 Issue
-
Possible Improvement
難度 2/5 1-3 小時 新手友好度 78/100
microsoft/TypeScript#64278 · 1 則留言 · 1 個 reaction ·
-
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 個 reaction ·
查看 microsoft/TypeScript 的全部 Issue
相似的 Issue
-
agentic-workflows
難度 2/5 1-3 小時 新手友好度 76/100
-
agentic-workflows
難度 2/5 1-3 小時 新手友好度 70/100
microsoft/agent-framework-go#1179 ·
-
bug
難度 2/5 1-3 小時 新手友好度 76/100
-
[Bug]: OLLAMA_KEEP_ALIVE="5m" / "24h" crashes Ollama embedding and vision models with ValueError 未關閉
難度 2/5 1-3 小時 新手友好度 75/100
infiniflow/ragflow#20223 · 1 個 reaction ·
-
bug needs triage pkg/translator/faro
難度 2/5 1-3 小時 新手友好度 88/100
open-telemetry/opentelemetry-collector-contrib#51484 · 1 則留言 ·