function first<T>(array: T[]): T | undefined;
function first<T>(array: T[], n: number): T[];
function first<T>(array: T[], n?: number): T | T[] | undefined;
With one argument first returns a single element, and undefined for an empty array rather than throwing — which is what spares every call site its own emptiness check. With a count it returns a new array instead, so the two forms never have to be told apart at runtime.
n is clamped the way Array#slice clamps: a negative count yields an empty array, a count beyond the length yields the whole array. The input is not modified.
Parameters
Parameter
Type
Description
array
T[]
The array to read from. Left untouched.
n(optional)
number
How many elements to take. An integer; omit it to take a single one.
Returns
T | T[] | undefined — T | undefined when n is omitted — the first element, or undefined for an empty array. T[] when n is given — a new array of at most n elements.
/**
* Splits a sheet into its header row and its data rows, and says so when the
* sheet turns out to be empty.
*/
export function readTable(sheet: GoogleAppsScript.Spreadsheet.Sheet): {
header: string[];
rows: string[][];
} {
const values = sheet.getDataRange().getValues() as string[][];
const header = first(values);
if (!header) {
throw new Error("The sheet is empty.");
}
return { header, rows: values.slice(1) };
}
function readTable(sheet) {
const values = sheet.getDataRange().getValues();
const header = first(values);
if (!header) {
throw new Error("The sheet is empty.");
}
return { header: header, rows: values.slice(1) };
}
Clamping
first([1, 2], 10); // => [1, 2] — never more than the array holds
first([1, 2], -1); // => []
first([1, 2], 1.5); // throws TypeError: Input 'n' must be an integer.