Generic extends type resolution

42 Views Asked by At

Given this function

export function filterMap2<TVal,TRet,TIter extends Iterable<TVal>=TVal[]>(obj: TIter, callback: (v: TVal, k: number, i: TIter) => TRet|symbol): TRet[] {
    let accum = [];

    let i = 0;
    for(let x of obj) {
        let y = callback(x, i++, obj);
        if(y !== __skip__) {
            accum.push(y as TRet);
        }
    }

    return accum;
}

And this test:

const numbers = [1, 2, 3, 4, 5];

expect(filterMap2(numbers, x => {
    if(x % 2 === 0) {
        return __skip__;
    }
    return x * 2;
})).toEqual([2, 6, 10]);

Typescript can't seem to resolve the type of x, even though numbers is clearly number[], which means IIter is number[], which means TVal must be a number.

If, however, I change the signature to:

 export function filterMap2<TVal,TRet>(obj: Iterable<TVal>, callback: (v: TVal, k: number, i: Iterable<TVal>) => TRet|symbol): TRet[] {

Then everything resolves fine. However, this signature is not as specific: I wanted to indicate that i is exactly the same type as obj.

Is this just a limitation of TypeScript, or have I done something wrong?

0

There are 0 best solutions below