mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-02 08:35:07 +08:00
Fix String conversion after union narrowing (#423)
- Extract primitive arms proven by TypeScript before string conversion. - Cover guarded record values in the differential corpus.
This commit is contained in:
@@ -5393,6 +5393,24 @@ export function ensureString(lowerer: Lowerer, e: IrExpr, node: ts.Node): IrExpr
|
||||
if (stringable) {
|
||||
return { kind: "toString", operand: e, type: STRING, loc: e.loc };
|
||||
}
|
||||
// Runtime-optional locals can retain their stored union after the
|
||||
// checker has narrowed this use to a primitive arm. Validate that
|
||||
// arm before converting it; an unguarded object arm stays fenced.
|
||||
const narrowed = lowerer.mapTypeOf(lowerer.typeOf(node));
|
||||
if (
|
||||
narrowed &&
|
||||
(narrowed.kind === "string" || narrowed.kind === "f64" ||
|
||||
narrowed.kind === "bool" || narrowed.kind === "bigint")
|
||||
) {
|
||||
const helper = lowerer.narrowedArmHelper(e.type.unionId, narrowed, e.loc);
|
||||
if (helper) {
|
||||
return ensureString(
|
||||
lowerer,
|
||||
{ kind: "call", callee: helper, args: [e], type: narrowed, loc: e.loc },
|
||||
node,
|
||||
);
|
||||
}
|
||||
}
|
||||
lowerer.unsupported(
|
||||
"SC1090",
|
||||
node,
|
||||
|
||||
@@ -6913,6 +6913,12 @@
|
||||
],
|
||||
"diags": []
|
||||
},
|
||||
"<repo>/tests/corpus/3024-string-number-narrow-for-in.ts": {
|
||||
"order": [
|
||||
"<repo>/tests/corpus/3024-string-number-narrow-for-in.ts"
|
||||
],
|
||||
"diags": []
|
||||
},
|
||||
"<repo>/tests/corpus/303-break-continue.ts": {
|
||||
"order": [
|
||||
"<repo>/tests/corpus/303-break-continue.ts"
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
type RelayHeaders = Record<string, string | string[] | number | undefined>;
|
||||
|
||||
function relayHeaders(source: RelayHeaders, strip: Set<string>): Record<string, string> {
|
||||
const headers: Record<string, string> = {};
|
||||
for (const name in source) {
|
||||
const value = source[name];
|
||||
if (value === undefined || strip.has(name.toLowerCase())) continue;
|
||||
if (typeof value === "string") {
|
||||
headers[name] = value;
|
||||
} else if (typeof value === "number") {
|
||||
headers[name] = String(value);
|
||||
} else {
|
||||
headers[name] = value.join(", ");
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(relayHeaders({ a: 1, b: ["x", "y"], c: "plain", d: undefined, E: 2 }, new Set(["e"]))));
|
||||
Reference in New Issue
Block a user