-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(core, rect): optional tokens #12
base: main
Are you sure you want to change the base?
Conversation
const foo = token('foo')<string | undefined>() | ||
const cb = jest.fn() | ||
const Component = () => { | ||
cb(useInjectable(foo)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line throws due to missing dependency in DependenciesProvider
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that instead of:
const foo = token('foo')<string | undefined>()
we should call it like that:
const foo = token('foo')<string>('defaultValue')
And then we can get this default value when call useInjectable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conceptually, a token can't have a default value because it's a pure "input", a slot where you have to pass a value. On the other hand, if you need default values - you need a "computation", an injectable: const foo = injectable('foo', (): string => 'defaultValue')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to support it we can do token like so:
export function token<Name extends PropertyKey>(name: Name) {
return <Type = never>(defaultValue?: Type): InjectableWithName<
{
readonly name: Name
readonly type: Type
readonly optional: undefined extends Type ? true : false
readonly children: readonly [
{
readonly name: typeof TOKEN_ACCESSOR_KEY
readonly type: TokenAccessor
readonly optional: true
readonly children: readonly []
}
]
},
Type
> => {
const f = (
dependencies: {
readonly [TOKEN_ACCESSOR_KEY]?: TokenAccessor
} & Record<Name, Type>
): Type => {
const accessor = dependencies[TOKEN_ACCESSOR_KEY]
if (accessor === undefined) {
return dependencies[name]
}
try {
return accessor(dependencies, name)
} catch (error) {
if (defaultValue === undefined) {
throw error
}
return defaultValue
}
}
f.key = name
// eslint-disable-next-line no-restricted-syntax
return f as never
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know we can, the issue is that it goes against the concept of a token.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can make it as special optionalToken.
I find it interesting only in case we have an ability to set default value as i have mentioned here:
#19
related to #3 - @Fyzu
NOTE: the test in
@injectable-ts/react
is failing due to missing dependency - need to find a way to fix it