I know this topic is quite old but for those wrestling with React and TypeScript this might be interesting.
I've made a Dashboard component, which has a nested Grid component, which has nested Widget components, which can get props for how many columns to span - and if no value is given it defaults to 1.
I didn't like the last item in a grid to 'not complete' a full block. With this code, the last item in the grid will stretch to the end of the last grid column. It calculates it's current position so if you have a grid with unknown grid items but still want a full block, this will come in handy.
And don't forget to give the grid element in the JSX the ref={gridRef} attribute :-)
const gridRef = useRef<HTMLDivElement>(null);
useLayoutEffect(() => {
    if (!gridRef.current) return;
    const widgets = gridRef.current.children as HTMLCollectionOf<HTMLDivElement>;
    const widgetsLeftPosition: number[] = [];
    const widgetsInLastRow: HTMLDivElement[] = [];
    // add offset from screenedge to array
    for (let i = 0; i < widgets.length; i++) {
        const currentWidgetLeftPosition = widgets[i].getBoundingClientRect().left;
        widgetsLeftPosition.push(currentWidgetLeftPosition);
    }
    // add elements (from rear end) to array, and
    // check if position of current element has same offset as first item, then break 
    // (which results in having only the elements of the last row in the array)
    for (let i = widgetsLeftPosition.length - 1; i >= 0; i--) {
        widgetsInLastRow.push(widgets[i]);
        if (widgetsLeftPosition[i] === widgetsLeftPosition[0]) break;
    }
    // for every element in the last row: check the gridColumnEnd value and
    // take the last character (which is a 'string-integer').
    // parse it to a normal integer, then sum up all integers and return that value
    const columnSpanStart = () => {
        let sum = 0;
        for (let i = 0; i < widgetsInLastRow.length; i++) {
            const spanString = getComputedStyle(widgetsInLastRow[i]).gridColumnEnd;
            sum += parseInt(spanString.slice(-1));
        }
        return sum;
    };
    // finally, use the returned value from columnSpanStart() as gridColumn 'start' value.
    // this will overwrite the default 'grid-column-end' style given by the widget component.
    const lastWidget = widgets[widgets.length - 1];
    lastWidget.style.gridColumn = `${columnSpanStart()} / -1`;
}, []);