Home > Blockchain >  Object Property method and have the good inference of the function in TypeScript
Object Property method and have the good inference of the function in TypeScript

Time:10-30

I want to type properly for Object method and have the good inference of the functions.

  const P = <T,>(x: T) => ({ "foo": (R: Function) => R(x) });

  const f = (a: number) => a   1;
  const g = (a: number) => a.toString();

  const p1 = f(5); //const p1: number         // good
  const p2 = g(5); //const p2: string         // good

  const q1 = P(5)['foo'](f); //const q1: any   // bad
  const q2 = P(5)['foo'](g); //const q2: any   // bad

  console.log(q1);
  console.log(q2);

TypeScript playground link

Any ideas? Thanks!

"use strict";
const P = (x) => ({ "foo": (R) => R(x) });

const f = (a) => a   1;
const g = (a) => a.toString();

const p1 = f(5); //const p1: number         // good
const p2 = g(5); //const p2: string         // good

const q1 = P(5)['foo'](f); //const q1: any   // bad
const q2 = P(5)['foo'](g); //const q2: any   // bad

console.log(q1);
console.log(q2);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Using the Function type is probably a bad idea; it represents an untyped function which accepts any parameters whatsoever and returns the unsafe any type. That means P is inferred to have the following type:

const P = <T,>(x: T) => ({ "foo": (R: Function) => R(x) });
/* const P: <T>(x: T) => {
  foo: (R: Function) => any;
} */

And so P(x).foo(y) will always return a value of type any for all x and y. Oops.


If you want the compiler to keep track of both the type of x and the return type of R you will need to make the returned function generic and give R an appropriate function type, like this:

const P = <T,>(x: T) => ({ "foo": <U,>(R: (x: T) => U) => R(x) });

Now it should work as desired:

const q1 = P(5)['foo'](f);
//const q1: number
console.log(q1.toFixed(2)) // "6.00"
const q2 = P(5)['foo'](g);
//const q2: string
console.log(q2.repeat(2)) // "55"

Playground link to code

  • Related