hegel
hegel copied to clipboard
Support for Existential Type (*)
supporting Existential Type will cut down boilerplate code that sometimes is needed to achieve same result for example
this
const FEATURES: $Immutable<{
FILTERING: 'Filtering',
REORDERING: 'Reordering',
SORTING: 'Sorting'
}> = {
SORTING: 'Sorting',
FILTERING: 'Filtering',
REORDERING: 'Reordering'
}
type Feature = $Values<$TypeOf<FEATURES>>
const features: Array<Feature> = []
void features.push('Filtering') // ok
void features.push(FEATURES.FILTERING) // ok
void features.push('foo') // error as expected
can be simplified to this
note: usage of FEATURES
is same so i removed it in following snippets
const FEATURES: $Immutable<*> = {
SORTING: 'Sorting',
FILTERING: 'Filtering',
REORDERING: 'Reordering'
}
so we say it will be Immutable but don't need to describe all properties and there values
there is two workarounds for this
one is to use Object.freeze
and freeze object on runtime as well
const FEATURES = Object.freeze({
SORTING: 'Sorting',
FILTERING: 'Filtering',
REORDERING: 'Reordering'
})
second is to create helper immutableId
function that will refine type but don't change value for runtime
const immutableId = <T>(v: T): $Immutable<T> => v
const FEATURES = immutableId({
SORTING: 'Sorting',
FILTERING: 'Filtering',
REORDERING: 'Reordering'
})
Looks good. But I want to add it as _
(underscore) syntax. Thank you for contribution ^_^.
This feature is called as const
in TS:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions
@amatiasq not true
"Existential Type" is completely different feature
as const
is hint for inference system to match type to value as close as possible so "Filtering"
is "Filtering"
not string
"Existential Type" is way of writing incomplete type definition that acts as constraints for inference system
I'm sorry I don't get what's Existential Type
then. I got confused by the original post where:
const FEATURES: $Immutable<{
FILTERING: 'Filtering',
REORDERING: 'Reordering',
SORTING: 'Sorting'
}> = {
SORTING: 'Sorting',
FILTERING: 'Filtering',
REORDERING: 'Reordering'
}
and
const FEATURES: $Immutable<*> = {
SORTING: 'Sorting',
FILTERING: 'Filtering',
REORDERING: 'Reordering'
}
Look to me like
const FEATURES = {
SORTING: 'Sorting',
FILTERING: 'Filtering',
REORDERING: 'Reordering'
} as const
I was looking for constant assertions when I found this issue should I create a different one then?
@amatiasq this issue touches on same use case as as const
but it's more complex feature then as const
so i think it's ok to create different issue for as const
and link to this issue as possible solution