Why do type parameters disappear in TypeScript?

It looks like TypeScript is not capable of expressing a function that takes a generic function as a parameter and returns a generic function. Note that the generic type <A>

becomes {}

in the following code example using a function doubleton

:

function compose<A, B, C>(
        g: (b: B) => C,
        f: (a: A) => B):  (a: A) => C {
    return a => g(f(a));
}

function singleton<A>(a: A): A[] { return [a]; }

// declare var doubleton: (a: {}) => {}[];
var doubleton = compose(singleton, singleton);

      

Oh no! We've lost our type parameter A

.

var x = 1; // number
var xs = singleton(x); // number[]
var xss = doubleton(x); // {}[]

      

And now we have seen the effects of loss of doubleton

community. Because of this, number

he became {}

.

Is there a way to tell make compose

to keep these type parameters other than defining doubleton

like this:

function doubleton<A>(a: A) { return [[a]]; }

      

I know this seems trivial in this example, but I've run into more complex return type cases (like auto-curry functions) where there is no need to repeat.

+3


source to share


1 answer


The problem seems to be related to the way information like the shape of the function signatures interacts with the shared parameters. for example a simpler example (based on yours) that fails:

function mirror<A, B>(f: (a: A) => B)
    : (a: A) => B {
    return f;
}

function singleton<A>(a: A): A[] { return [a]; }

// (a:{})=>{}[]
var singletonMirror = mirror(singleton);

var x = 1;
var xs = singleton(x); // number[]
var xsM = singletonMirror(x); // {}[]

      

Will work unless you ask the type system to infer to A

and B

from f

:

function mirror<T>(f: T)
    : T {
    return f;
}

function singleton<A>(a: A): A[] { return [a]; }

// okay
var singletonMirror = mirror(singleton);

var x = 1;
var xs = singleton(x); // number[]
var xsM = singletonMirror(x); // number[]

      



I would report this as an issue: https://github.com/microsoft/typescript/issues

Further simplification of the error:

function unity<A>(f: (a: A) => A)
    : (a: A) => A {
    return f;
}

function mirror<T>(a: T): T { return a; }

// (a:{})=>{}, should be (a:T)=>T
var unityMirror = unity(mirror);

      

+2


source







All Articles