mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
`options.sessionId` inside a generic function whose type parameter's
constraint declares `sessionId?: string` fenced with SC1090 when the call
site's options record has no such slot:
function applyAuth<TModel, TOptions extends ProviderRequestOptions<TModel> & Transforms>(
model: TModel, options: TOptions | undefined) {
const sessionId =
options && "sessionId" in options && typeof options.sessionId === "string"
? options.sessionId : undefined;
}
applyAuth(model, { apiKey, azureApiVersion });
The checker admits the read through the constraint (and, with the `in`
guard, through a synthetic `T & Record<"sessionId", unknown>`), while the
instantiated record — the value's actual layout — stores no such field.
`fieldTarget` found no record slot and the read fell through to the
generic unsupported-property fence, even though Node simply reads the
property off the object it has: undefined when the caller omitted it, the
extra property when a JavaScript caller supplied one.
fieldTarget now recognizes a generic receiver (a type parameter, or an
`in`-narrowed intersection that contains one) whose stored record lacks
the member, and lowers the read as the checked-dynamic keyed read of that
record value, entering the static code at the type the checker gave the
read. Reads that keep a slot take their record get as before, and the
programs this path opens did not compile at all before, so typed code
keeps its representation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>