#Generics and functions

22 messages · Page 1 of 1 (latest)

stiff ferryBOT
#
m.a.t.t.t#0

Preview:```ts
type Foo = <C>(input?: C) => C

const x: Foo = (input = 0) => input```

snow trellis
#

Foo is defined in a reusable library

and input in this case is a cursor value. The resuable library does no computation on it, it just stores the value and returns it on a subsequent call to Foo

so its trying to say it will accept C but the provider of the function can define their own Foo without losing its concrete type in the return value

red parrot
#

There's just no way to implement Foo safely.

#

Both foo<T>() and foo<U>() compile to foo() in JS, there's no way for foo to know what T or U is to return it.

#

Your x is implemented wrong because for example x<string>() will return 0 even though it's supposed to be string.

snow trellis
#

hmm im not following... x returns the same type as it receives, so it meets the contract for Foo?

#

i know im wrong im just trying to understand how

red parrot
#

What should x<string>() return?

snow trellis
#

here's maybe an example of how the library uses foo

function lib(foo: Foo) {
  let lastCursor
  function next() {
    lastCursor = foo(lastCursor)
  }
  ...
}
#

oh i didnt know you could do x<string> because I put the generic on the RHS of = ie. its not Foo<C> = its Foo = <C>

red parrot
#

Yeah those two are different.

snow trellis
#

hmm i wonder how to solve this, the library in the example code above just needs to store the last value and return it when invoking the callback on the next run

the consumer of the library should be able to hav final say on string | number | SomeClass etc... as lib does not care, it does not perform any calculation on it, only stores it in state between invocations

red parrot
#

Are you in control of the library?

snow trellis
#

yeah the library and the consumer libraries

the cursor is a string in some places and a number in others, and possibly an object in some places

I suppose I could just make cursor always a string and then the consumer needs to encode/decode each time?

red parrot
#

Foo just simply cannot be implemented safely for the reason I explained above, you might want to explain what you are trying to do so people can suggest an alternative design.

#

Foo is the same as magicallyCreate<T>().

snow trellis
#

i feel like what i have explained is sufficient, especially with the example code i provided in terms how the library consumes the generic

#
function lib(foo: Foo) {
  let lastCursor
  function next() {
    lastCursor = foo(lastCursor)
  }
  ...
}
red parrot
#

Does the lib know what lastCursor is supposed to be?

snow trellis
#

see how the library does not care what the cursor is, its just storing it in closure state

#

ok nevermind, i'll just make it string always and every single consumer can encode and decode from/to strings

red parrot
#

You can also lift the generic up to lib.