mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-02 07:43:42 +08:00
Array reduce typed its accumulator by the call's checked type, widened with undefined only when the callback could return a missing value or a receiver without an initial value could have holes. Three runtime values fell outside it and threw "not representable in the target union": - an initial value read from a missing element; - a callback result of another primitive (`missing[0] ?? "fallback"`); - a callback wrapped in parentheses, which the analysis and the callback lowering did not see as the arrow it wraps. The accumulator now also takes undefined from a possibly missing initial value, and the primitive arms the callback's result can have. Array callbacks are taken without their parentheses. `arguments.length` in a fixed-arity function expression folded to its declared parameter count. When the expression flows into a fixed-arity function type with more parameters, as array callbacks do (value, index, array, and the accumulator for reduce), every call passes that type's count, and the length is that count.
43 lines
1.1 KiB
TypeScript
43 lines
1.1 KiB
TypeScript
// `arguments.length` in a function-expression callback counts every
|
|
// argument the array method passes: value, index and array, plus the
|
|
// accumulator for reduce. One stored in a fixed-arity function type counts
|
|
// that type's parameters, which every call passes.
|
|
const seen: number[] = [];
|
|
[10, 20].forEach(function (value) {
|
|
seen.push(arguments.length, value);
|
|
});
|
|
console.log(seen.join(","));
|
|
|
|
console.log(
|
|
[1, 2]
|
|
.map(function (value) {
|
|
return `${value}:${arguments.length}`;
|
|
})
|
|
.join(" "),
|
|
);
|
|
|
|
console.log([5].filter(function () {
|
|
return arguments.length === 3;
|
|
}).length);
|
|
|
|
console.log([1].reduce(function (acc, value) {
|
|
return acc + value + arguments.length;
|
|
}, 0));
|
|
|
|
console.log(["x", "y"].reduceRight(function (acc: string, value: string) {
|
|
return `${acc}${value}${arguments.length}`;
|
|
}, ""));
|
|
|
|
console.log([3, 4].some(function (value) {
|
|
return arguments.length === 3 && value === 4;
|
|
}));
|
|
|
|
const sum: (a: number, b: number) => number = function (a) {
|
|
return a + arguments.length;
|
|
};
|
|
console.log(sum(1, 2));
|
|
|
|
console.log([3, 1, 2].sort(function (a, b) {
|
|
return arguments.length === 2 ? a - b : 0;
|
|
}).join(","));
|