mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-29 07:04:09 +08:00
Dispatch splice on arrays of unknown elements (#1935)
This commit is contained in:
@@ -361,6 +361,21 @@ export function lowerArrayMethodCall(
|
||||
if (probe.type.kind === "array") {
|
||||
receiverIr = probe.type;
|
||||
probedUntyped = true;
|
||||
} else if (
|
||||
probe.type.kind === "dyn" &&
|
||||
!isJsSourceFile(ts.getSourceFileOfNode(access)) &&
|
||||
lowerer.isStdlibMember(access)
|
||||
) {
|
||||
// An `unknown[]` (or `any[]`) array stored checked-dynamic — a
|
||||
// generic body instantiated at `unknown`, a spread of unknown
|
||||
// elements: the method runs on the runtime array (dynInvoke, JS
|
||||
// exact), and a typed result is checked like any member read.
|
||||
const dispatched = lowerDynDispatchMethodCall(lowerer, call, access, probe, true);
|
||||
if (!dispatched) return null;
|
||||
const result = lowerer.mapTypeOf(lowerer.typeOf(call));
|
||||
return result && result.kind !== "void" && result.kind !== "dyn"
|
||||
? lowerer.coerceInto(call, dispatched, result)
|
||||
: dispatched;
|
||||
}
|
||||
}
|
||||
if (receiverIr?.kind === "union") {
|
||||
|
||||
@@ -4261,6 +4261,7 @@ const DYN_DISPATCH_METHODS = new Set([
|
||||
"shift",
|
||||
"unshift",
|
||||
"slice",
|
||||
"splice",
|
||||
"at",
|
||||
"indexOf",
|
||||
"lastIndexOf",
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/corpus/7402-unknown-array-methods.ts"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Methods on arrays of unknown elements, which are stored checked-dynamic:
|
||||
// direct `unknown[]` bindings and generic bodies instantiated at `unknown`.
|
||||
const values: unknown[] = [1, "two", 3, { four: 4 }];
|
||||
const removed = values.splice(1, 2);
|
||||
console.log(values, removed, removed.length);
|
||||
values.splice(1, 0, "inserted", null);
|
||||
console.log(values, values.indexOf(null), values.includes("inserted"));
|
||||
console.log(values.slice(1).reverse(), values.join("|"));
|
||||
|
||||
function takeAt<T>(items: readonly T[], index: number): T[] {
|
||||
const pool = [...items];
|
||||
return pool.splice(index, 1);
|
||||
}
|
||||
console.log(takeAt([10, 20, 30], 1), takeAt<unknown>([true, "x", 7], 2));
|
||||
@@ -0,0 +1 @@
|
||||
{ "plain": 2600, "san": 20000 }
|
||||
Reference in New Issue
Block a user