Error transforming object

I'm having some trouble doing transforming some data
3 Replies
SynthLuvr
SynthLuvr4mo ago
const MyAssets = scope({
Asset: {
token: "string",
amount: type("string").pipe((s, ctx) => {
try {
return BigInt(s);
} catch {
return ctx.error("a valid non-decimal number");
}
}),
},
Assets: {
assets: "Asset[]>=1",
},
})
.export()
.Assets.pipe((o) => {
const assets = o.assets.reduce<Record<string, bigint>>((acc, asset) => {
acc[asset.token] = asset.amount;
return acc;
}, {});
return { ...o, assets };
});

test("can parse MyAssets", (t) => {
const data = MyAssets({ assets: [{ token: "a", amount: "1" }] });
if (data instanceof type.errors) return t.fail(data.summary);
t.truthy(data);
});
const MyAssets = scope({
Asset: {
token: "string",
amount: type("string").pipe((s, ctx) => {
try {
return BigInt(s);
} catch {
return ctx.error("a valid non-decimal number");
}
}),
},
Assets: {
assets: "Asset[]>=1",
},
})
.export()
.Assets.pipe((o) => {
const assets = o.assets.reduce<Record<string, bigint>>((acc, asset) => {
acc[asset.token] = asset.amount;
return acc;
}, {});
return { ...o, assets };
});

test("can parse MyAssets", (t) => {
const data = MyAssets({ assets: [{ token: "a", amount: "1" }] });
if (data instanceof type.errors) return t.fail(data.summary);
t.truthy(data);
});
Error thrown in test:

TypeError {
message: 'Cannot read properties of undefined (reading \'amount\')',
}
Error thrown in test:

TypeError {
message: 'Cannot read properties of undefined (reading \'amount\')',
}
If amount doens't include the pipe, then it works:
const MyAssets = scope({
Asset: {
token: "string",
amount: "string",
},
Assets: {
assets: "Asset[]>=1",
},
})
.export()
.Assets.pipe((o) => {
const assets = o.assets.reduce<Record<string, bigint>>((acc, asset) => {
acc[asset.token] = BigInt(asset.amount);
return acc;
}, {});
return { ...o, assets };
});
const MyAssets = scope({
Asset: {
token: "string",
amount: "string",
},
Assets: {
assets: "Asset[]>=1",
},
})
.export()
.Assets.pipe((o) => {
const assets = o.assets.reduce<Record<string, bigint>>((acc, asset) => {
acc[asset.token] = BigInt(asset.amount);
return acc;
}, {});
return { ...o, assets };
});
If I rename assets instead of transforming, it works:
const MyAssets = scope({
Asset: {
token: "string",
amount: type("string").pipe((s, ctx) => {
try {
return BigInt(s);
} catch {
return ctx.error("a valid non-decimal number");
}
}),
},
Assets: {
assets: "Asset[]>=1",
},
})
.export()
.Assets.pipe((o) => {
const assets = o.assets.reduce<Record<string, bigint>>((acc, asset) => {
acc[asset.token] = asset.amount;
return acc;
}, {});
return { ...o, assets2: assets };
});
const MyAssets = scope({
Asset: {
token: "string",
amount: type("string").pipe((s, ctx) => {
try {
return BigInt(s);
} catch {
return ctx.error("a valid non-decimal number");
}
}),
},
Assets: {
assets: "Asset[]>=1",
},
})
.export()
.Assets.pipe((o) => {
const assets = o.assets.reduce<Record<string, bigint>>((acc, asset) => {
acc[asset.token] = asset.amount;
return acc;
}, {});
return { ...o, assets2: assets };
});
Also fails:
const Assets = scope({
Asset: {
token: "string",
amount: type("string").pipe((s, ctx) => {
try {
return BigInt(s);
} catch {
return ctx.error("a valid non-decimal number");
}
}),
},
Assets: "Asset[]",
})
.export()
.Assets.pipe((a) =>
a.reduce<Record<string, bigint>>((assets, asset) => {
assets[asset.token] = asset.amount;
return assets;
}, {})
);

const MyAssets = scope({
AssetsType: Assets,
Assets: {
assets: "AssetsType",
},
}).export().Assets;
const Assets = scope({
Asset: {
token: "string",
amount: type("string").pipe((s, ctx) => {
try {
return BigInt(s);
} catch {
return ctx.error("a valid non-decimal number");
}
}),
},
Assets: "Asset[]",
})
.export()
.Assets.pipe((a) =>
a.reduce<Record<string, bigint>>((assets, asset) => {
assets[asset.token] = asset.amount;
return assets;
}, {})
);

const MyAssets = scope({
AssetsType: Assets,
Assets: {
assets: "AssetsType",
},
}).export().Assets;
My current working solution is to wrap the type:
const MyAssets = (() => {
const MyAssets = scope({
Asset: {
token: "string",
amount: type("string").pipe((s, ctx) => {
try {
return BigInt(s);
} catch {
return ctx.error("a valid non-decimal number");
}
}),
},
Assets: {
assets: "Asset[]>=1",
},
}).export().Assets;

return (data: unknown) => {
const result = MyAssets(data);
if (result instanceof type.errors) return result;

return {
...result,
assets: result.assets.reduce<Record<string, bigint>>((acc, asset) => {
acc[asset.token] = asset.amount;
return acc;
}, {}),
};
};
})();

test("can parse MyAssets", (t) => {
const data = MyAssets({ assets: [{ token: "a", amount: "1" }] });
if (data instanceof type.errors) return t.fail(data.summary);
t.truthy(data);
});
const MyAssets = (() => {
const MyAssets = scope({
Asset: {
token: "string",
amount: type("string").pipe((s, ctx) => {
try {
return BigInt(s);
} catch {
return ctx.error("a valid non-decimal number");
}
}),
},
Assets: {
assets: "Asset[]>=1",
},
}).export().Assets;

return (data: unknown) => {
const result = MyAssets(data);
if (result instanceof type.errors) return result;

return {
...result,
assets: result.assets.reduce<Record<string, bigint>>((acc, asset) => {
acc[asset.token] = asset.amount;
return acc;
}, {}),
};
};
})();

test("can parse MyAssets", (t) => {
const data = MyAssets({ assets: [{ token: "a", amount: "1" }] });
if (data instanceof type.errors) return t.fail(data.summary);
t.truthy(data);
});
ssalbdivad
ssalbdivad4mo ago
Will need to investigate this one more, can you log it as a GitHub issue? You can log the other one as well though that should be more straightforward to repro/fix
SynthLuvr
SynthLuvr4mo ago
GitHub
Error transforming object: Cannot read properties of undefined · Is...
Report a bug 🔎 Search Terms pipe transform 🧩 Context ArkType version: 2.0.0-dev.13 TypeScript version (5.1+): 5.3.3 Other context you think may be relevant (JS flavor, OS, etc.): 🧑‍💻 Repro const My...
Want results from more Discord servers?
Add your server