mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-02 00:25:34 +08:00
* Fix Record array index property reads (#400) - Narrow optional record receivers before keyed reads. - Cover present and missing rows with differential tests. * Record TypeScript 7 baseline for Record array fixture - Add the new corpus program to the preflight and module order baseline. * Stabilize HTTP timeout differential fixtures - Release server responses after timeout callbacks. - Bound missing callbacks with fallback responses.
This commit is contained in:
@@ -9316,7 +9316,24 @@ export function lowerBinary(lowerer: Lowerer, expr: ts.BinaryExpression): IrExpr
|
||||
// construction), typed as the index value armed with undefined under
|
||||
// noUncheckedIndexedAccess (mirroring lowerRecordKeyRead).
|
||||
if (target.container === "recordOvf") {
|
||||
let t: IrType = target.fieldType;
|
||||
let obj = target.obj;
|
||||
if (obj.type.kind === "union" && ts.isPropertyAccessExpression(blame)) {
|
||||
const present = lowerer.stripUndefinedArm(obj.type);
|
||||
if (present.kind === "record") {
|
||||
obj = lowerer.runtimeOptionalPropertyReceiver(
|
||||
blame.expression,
|
||||
obj,
|
||||
present,
|
||||
target.field,
|
||||
) ?? obj;
|
||||
}
|
||||
}
|
||||
if (obj.type.kind !== "record") {
|
||||
lowerer.unsupported("SC1090", blame, `reading '${target.field}' on a non-record receiver (narrow first)`);
|
||||
}
|
||||
const shape = lowerer.shapes.get(obj.type.shapeId);
|
||||
if (!shape?.indexValue) lowerer.unsupported("SC1090", blame, `reading '${target.field}' on a record without an index signature`);
|
||||
let t: IrType = shape.indexValue;
|
||||
if (lowerer.program.getCompilerOptions().noUncheckedIndexedAccess) {
|
||||
const armed = lowerer.withUndefinedArmOf(t);
|
||||
if (!armed) lowerer.badType(blame, lowerer.typeOf(blame));
|
||||
@@ -9324,8 +9341,8 @@ export function lowerBinary(lowerer: Lowerer, expr: ts.BinaryExpression): IrExpr
|
||||
}
|
||||
return {
|
||||
kind: "recordKeyGet",
|
||||
obj: target.obj,
|
||||
shapeId: target.shapeId,
|
||||
obj,
|
||||
shapeId: obj.type.shapeId,
|
||||
key: { kind: "strLit", value: target.field, type: STRING, loc },
|
||||
overflowOnly: true,
|
||||
type: t,
|
||||
|
||||
@@ -7581,6 +7581,12 @@
|
||||
],
|
||||
"diags": []
|
||||
},
|
||||
"<repo>/tests/corpus/917-record-array-index-dot.ts": {
|
||||
"order": [
|
||||
"<repo>/tests/corpus/917-record-array-index-dot.ts"
|
||||
],
|
||||
"diags": []
|
||||
},
|
||||
"<repo>/tests/corpus/950-modules-basic/main.ts": {
|
||||
"order": [
|
||||
"<repo>/tests/corpus/950-modules-basic/util.ts",
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
type Row = Record<string, string | number | null>;
|
||||
|
||||
function firstId(rows: Row[]): number {
|
||||
return rows[0].id as number;
|
||||
}
|
||||
|
||||
console.log(firstId([{ id: 1 }]));
|
||||
|
||||
let evaluations = 0;
|
||||
function makeRows(): Row[] {
|
||||
evaluations++;
|
||||
return [{ id: evaluations }];
|
||||
}
|
||||
console.log(makeRows()[0].id, evaluations);
|
||||
|
||||
try {
|
||||
firstId([]);
|
||||
} catch (error) {
|
||||
console.log(error instanceof TypeError, (error as Error).message);
|
||||
}
|
||||
Reference in New Issue
Block a user