AndyBan
AndyBan

Reputation: 105

Typescript type narrowing

I have a bit of a code rendering a tab control which is looking at the react children being passed in but I don't know if its a single item or an array. Is there a cleaner way of doing this without using an any? I tried to get type narrowing working but wasn't successful.

EnsureArray<T>(input: T | ReadonlyArray<T> | undefined): ReadonlyArray<T>  {
    if (!input) {
        return [];
    }
    if ((input as any).length !== undefined) {
        return input as T[];
    }
    return [input as T];
}

renderActiveContent() {
    const items = this.EnsureArray(this.props.children);
    const tab =  items.find(c => c.props.name === this.props.SelectedTab) || items[0];
    return tab && tab.props && tab.props.children;
}

Upvotes: 1

Views: 329

Answers (2)

Matt Strom
Matt Strom

Reputation: 615

I would do something like

EnsureArray<T extends React.Component>(inputs: ReadonlyArray<T>): ReadonlyArray<T>;
EnsureArray<T extends React.Component>(input: T): T[];
EnsureArray<T extends React.Component>(input: T | ReadonlyArray<T> | undefined): any[] {
    if (input === undefined) { return []; }

    return Array.isArray(input)
        ? input
        : [input];
}

Upvotes: 1

Ivan Sanz Carasa
Ivan Sanz Carasa

Reputation: 1387

Check if its an array with Array.isArray(input) or input instanceof Array

https://www.w3schools.com/jsref/jsref_isarray.asp

if (Array.isArray(input)) return input;
if (input === undefined) return [];
return [input];

Upvotes: 3

Related Questions