Question: Casting type / infering type
Closed this issue · 3 comments
I'm struggling to understand how to satisfy TypeScript when using ts-belt. Appreciate any help
How do I cast array of numbers from splitting the string?
Is this the right approach of such ?
const sample1 = "2x3x4";
_.pipe(
sample1,
_.F.coerce<() => [number, number, number]>(_.S.split("x")),
_.O.flatMap(([l, w, h]) => 2 * l * w + 2 * w * h + 2 * h * l)
);
or
const data = `azs
20x3x11
15x27x5
6x29x7`
const getSurfaceArea = (input: number[]) =>
_.pipe(
input,
_.O.flatMap(([l, w, h]) => {
if (!l || !w || !h) return 0;
const squareFeetArea = 2 * l * w + 2 * w * h + 2 * h * l;
const smallestSide = Math.min(l * w, w * h, h * l);
return squareFeetArea + smallestSide;
})
);
const totalSquareFeet = _.pipe(
data,
_.S.split("\n"),
_.A.map((el) => _.A.map(_.S.split("x")(el), Number).filter(Boolean)),
_.A.map(getSurfaceArea),
_.A.reduce(0, _.N.add)
);
console.log(totalSquareFeet);
TS2345: Argument of type '(xs: readonly number[][]) => readonly Option[]' is not assignable to parameter of type '(arg: readonly number[][]) => readonly number[]'. Type 'readonly Option[]' is not assignable to type 'readonly number[]'. Type 'Option' is not assignable to type 'number'. Type 'undefined' is not assignable to type 'number'.
how to handle typing of Option/Result
Clearly I can't wrap my head around how to properly compose functions in order for types to be properly inferred.
What I'm doing wrong here so the types don't cascade properly?
const sortAscending = _.A.sort((a: number, b: number) => a - b);
const mapEquations = _.flow(
_.S.split("\n"),
_.A.map((el) => _.A.map(_.S.split("x")(el), Number).filter(Boolean))
);
const calculateSum = _.A.reduce([0, 0], (acc, next) => {
// @ts-ignore
const paper = acc[0] + next[0];
// @ts-ignore
const ribbon = acc[1] + next[1];
return [paper, ribbon];
});
const calculateSurface = _.O.flatMap(([l, w, h]) => {
if (!l || !w || !h) return 0;
const boxSurfaceArea = 2 * l * w + 2 * w * h + 2 * h * l;
const boxSurface = boxSurfaceArea + l * w;
const ribbonSurface = 2 * l + 2 * w + l * w * h;
return [boxSurface, ribbonSurface];
}) as (arr: number[]) => [number, number];
const totalSquareFeet = _.pipe(
data,
mapEquations,
// @ts-ignore
_.A.map(sortAscending),
_.A.map(calculateSurface),
calculateSum
);
console.log(totalSquareFeet);
@stychu hello! 👋 I'm not sure why you're using the Option
data type, since none of the utils you use don't return Option
(for instance: you use S.split
which doesn't return Option
)
the solution for the first code snippet:
import { pipe, flow, A, N, S, F } from "@mobily/ts-belt";
const data = `azs
20x3x11
15x27x5
6x29x7`;
const getSurfaceArea = (input: readonly [number, number, number]) => {
const [l, w, h] = input;
const squareFeetArea = 2 * l * w + 2 * w * h + 2 * h * l;
const smallestSide = Math.min(l * w, w * h, h * l);
return squareFeetArea + smallestSide;
};
const totalSquareFeet = pipe(
data,
S.split("\n"),
A.map(
flow(
S.split("x"),
F.ifElse(
(xs) => xs.length === 3,
(values) => {
return getSurfaceArea(F.coerce(values));
},
F.always(0)
)
)
),
A.reduce(0, N.add)
);
console.log(totalSquareFeet);