1
votes

Type inference in TypeScript is amazing. Nevertheless I have a case where I thought TypeScript could infer the corresponding type, but it does not. Now I ask myself if that's just not possible for TypeScript in that particular use case or wheter I did something wrong (or at least have to change something to make it work).

Actually, in the following example (a very simple and tiny store implementation) I would like to get rid of that explicit type Store = ... declaration and would like to replace that createStore<Store>(...) by just createStore(...) as I think that type should be inferred by the return value below. Is this somehow possible?

function createStore<T>(init: (self: T) => T): T {
  // just ignore that this is not implemented here
}

type Store = {
  count: number,
  increment(): void
}

// I want to get rid of <Store> in the following line - any ideas?
const store = createStore<Store>(self => {
  return { 
    count: 0,

    increment() {
      self.count++
    }  
  }
})

console.log(store.count) // prints out 0
store.increment()
console.log(store.count) // prints out 1

If a working demo might help, please see: https://stackblitz.com/edit/typescript-huvdpc


[Edit] Just fyi, with Flow type inference seems to work fine in this use case:

/* @flow */

function createStore<T>(init: (self: T) => T): T {
  const ret: T = (({}: any): T)
  Object.assign(ret, init(ret))
  return ret
}

const store = createStore(self => {
  return {
     count: 0,

     increment() {
       self.count++
     }
  }
})

console.log(store.count) // prints out 0
store.increment()
console.log(store.count) // prints out 1

[Edit: Some hours later]

Judging by the comments below, it seems that it's not be possible to achieve type inference the way I would like it in the above example.

Here's basically the same thing in a different implementation where type inference is working as desired:

https://stackblitz.com/edit/typescript-7olxbc

1
"I would like to get rid of that explicit" --- if you remove the explicit Store type - then it would be impossible to type self: what would guarantee it has a count property?zerkms
Not possible, just keep passing Store type argument, seems to be perfectly OK here.Nurbol Alpysbayev
Thanks a lot zerkms and NurbolAlpysbayev for your answers. That means I have to refactor that stuff somehow. I've added a link to a new implementation which supports the desired type inference to the summery above: stackblitz.com/edit/typescript-7olxbcNatasha
You can move the type annotation on const store: Store but that is about it.Titian Cernicova-Dragomir

1 Answers

0
votes

Typescript does not (at least not in the current version 3.3.x) support type inference if a functions has the kind of "argument"-"return value"-circularity as in the example above.

Nevertheless, Flow is supporting this kind of type inference.