Hegel: Support for Existential Type (*)

Created on 29 Apr 2020  路  5Comments  路  Source: JSMonk/hegel

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'
})
enhancement

Most helpful comment

Looks good. But I want to add it as _ (underscore) syntax. Thank you for contribution ^_^.

All 5 comments

Looks good. But I want to add it as _ (underscore) syntax. Thank you for contribution ^_^.

@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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Mathspy picture Mathspy  路  5Comments

karimsa picture karimsa  路  4Comments

munizart picture munizart  路  3Comments

leushkin picture leushkin  路  4Comments

millsp picture millsp  路  3Comments