hegel icon indicating copy to clipboard operation
hegel copied to clipboard

Support for Existential Type (*)

Open thecotne opened this issue 4 years ago • 5 comments

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

thecotne avatar Apr 29 '20 11:04 thecotne

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

JSMonk avatar Apr 29 '20 22:04 JSMonk

This feature is called as const in TS: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions

amatiasq avatar Dec 03 '20 13:12 amatiasq

@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

thecotne avatar Dec 03 '20 13:12 thecotne

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 avatar Dec 03 '20 14:12 amatiasq

@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

thecotne avatar Dec 03 '20 14:12 thecotne