Home > Blockchain >  How can I make typescript restrict array type based on filter inference?
How can I make typescript restrict array type based on filter inference?

Time:12-11

This will never fail to return an array of strings:

(arr: (string | undefined)[]): string[] => arr.filter(item => item !== undefined);

playground link

But TypeScript does not accept to compile this because it doesn't infer that the filter predicate will return true if and only item is a string. Explicitly typing the predicate doesn't seem to help either:

const predicate = (item: string | undefined): item is string => item !== undefined;
(arr: (string | undefined)[]): string[] => arr.filter(item => predicate(item));

playground link

This works but is much wordier (and if I'm not mistaken, much slower):

(arr: (string | undefined)[]): string[] => {
    const ret: string[] = [];
    for (const item of arr) {
        if (item !== undefined) {
            ret.push(item);
        }
    }
    return ret;
}

playground link

Is there an experimental flag I can enable in my tsconfig.json that'll enable TypeScript to make type inferences based on the .filer predicate?

CodePudding user response:

You are using an anonymous inline function instead of the predicate:

TS Playground link

const predicate = (item: string | undefined): item is string => item !== undefined;

(arr: (string | undefined)[]): string[] => arr.filter(item => predicate(item)); // error

(arr: (string | undefined)[]): string[] => arr.filter(predicate); // ok

// inline predicate
(arr: (string | undefined)[]): string[] => arr.filter((item): item is string => item !== undefined);

CodePudding user response:

You can use something like this this

(arr: (string | undefined)[]): string[] => arr.filter(String) as string[];

  • Related