Files
scriptc/tests/corpus/spread-empty-default.ts
T
Malte UblandClaude Opus 5.5 b0bbae15ac Spread an empty-object default like its source
`...(x ?? {})` and `...(x || {})` spread exactly what `...x` spreads, but
the defaulted source lowered as a `??` expression into a checked-dynamic
value, which failed for records with function fields. When x is a record
or an optional record, the spread now lowers as a spread of x.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 05:37:45 -07:00

46 lines
1.8 KiB
TypeScript

// `...(options ?? {})` and `...(options || {})` spread exactly what
// `...options` spreads: nullish and other falsy values contribute no keys.
// The optional source is an Omit<> view of an options interface whose
// fields include a function, so a checked-dynamic copy cannot hold it.
interface LoaderOptions {
cwd: string;
agentDir: string;
extraPaths?: string[];
onLoad?: (paths: string[]) => string[];
}
interface ServiceOptions {
cwd: string;
loaderOptions?: Omit<LoaderOptions, "cwd" | "agentDir">;
}
class Loader {
readonly options: LoaderOptions;
constructor(options: LoaderOptions) {
this.options = options;
}
describe(): string {
const paths = this.options.onLoad?.(this.options.extraPaths ?? []) ?? [];
return `${this.options.cwd} ${this.options.agentDir} [${paths.join(",")}]`;
}
}
function viaNullish(options: ServiceOptions): Loader {
return new Loader({ ...(options.loaderOptions ?? {}), cwd: options.cwd, agentDir: "/agent" });
}
function viaOr(options: ServiceOptions): Loader {
return new Loader({ cwd: options.cwd, agentDir: "/or", ...(options.loaderOptions || {}) });
}
let evaluated = 0;
function counted(options: ServiceOptions): ServiceOptions["loaderOptions"] {
evaluated++;
return options.loaderOptions;
}
function viaCall(options: ServiceOptions): Loader {
return new Loader({ ...(counted(options) ?? {}), cwd: options.cwd, agentDir: "/call" });
}
const bare: ServiceOptions = { cwd: "/w" };
const full: ServiceOptions = { cwd: "/w", loaderOptions: { extraPaths: ["x"], onLoad: (p) => [...p, "y"] } };
console.log(viaNullish(bare).describe());
console.log(viaNullish(full).describe());
console.log(viaOr(bare).describe());
console.log(viaOr(full).describe());
console.log(viaCall(bare).describe(), viaCall(full).describe(), evaluated);