raveclassic/injectable-ts

Optional token proposal

Opened this issue · 1 comments

Hello!

If we imagine some kind of service which behaviour can be controlled outside (for example auth tokens), we would use tokens for that like so:

const myService = injectable('myService', token('authToken')<string>(), (token) => {
   ...
})

But what if we want to have some default behaviour or initial state for the service? We can't provide a default value for a token.
To get same result we can do it like so:

const myValue = injectable('authToken', () => 'defaultToken')
const myService = injectable('myService', myValue, (token) => {
   ...
})

Which is ok and work, but it seems inconsistent to use different ways for close purposes.
So, I would like to offer to make an optional token like so:

token('authToken')<string>('defaultToken')
/// or
optionalToken('authToken')<string>('defaultToken') // here we will force user to set default value

Hey @coolassassin, thanks for the proposal.
While I see some benefits here I also see that this would bloat the API: optionalToken('authToken')<string>('defaultToken') is essentially an alias to injectable('authToken', (): string => 'defaultToken').

Regarding inconsistency, I'm not sure I'm following since current implementation is consistent with the statement that a "token" is a dependency that the caller must provide when invoking the computation, and "injectable" is a computation itself with a default value which can be overridden.

The above means that if you want an optional dependency - you'd typically declare it as token('dependency')<string | undefined>(), but you'd have to explicitly provide the key - root({ dependency: undefined }).

I might be missing something here, but for now the current state of things seems consistent to me. Still, let's keep this open so that we could all think about this a bit more.