Skip to content

Instantly share code, notes, and snippets.

@fvilante
Last active March 5, 2019 06:11
Show Gist options
  • Save fvilante/992f3baa04745c9edf3d5d4586f020b4 to your computer and use it in GitHub Desktop.
Save fvilante/992f3baa04745c9edf3d5d4586f020b4 to your computer and use it in GitHub Desktop.
Comparisson of alternative type parameter naming in Typescript
// A study on alternative forms to name Typescript Type parameters
// original thread: https://twitter.com/sompylasar/status/1102446254292983808
// *********************************
// T,U,V convention
// *********************************
type InferMaybeType<T> = T extends Maybe<infer U> ? U : never
type Maybe_<T> = Maybe<InferMaybeType<T>> // helper for brevity
type GetMaybeConstructors<T extends Maybe_<T>> = T['val']['type']
type CallBack<T, U> = (value: T) => U
type Match<T extends Maybe_<T>> = {
[Constructor in GetMaybeConstructors<T>]: CallBack< InferMaybeType<T>, unknown >
}
// ****************************************
// Meaningful semantics- in two passes
// ****************************************
// Rational: In firs pass, T stands for AnyType, if there is more than one parameter like T, U, a numerical index is postfixed,
// ie: T = AnyType0 and U = AnyType1. After naming variables in this way a second pass is done trying to rename
// variables to a more meaningful name, in this pass programmer may insert a semantics that express better his
// intents
// *** first pass ****
type InferMaybeType<AnyType_0> = AnyType_0 extends Maybe<infer AnyType_1> ? AnyType_1 : never
type Maybe_<AnyType> = Maybe<InferMaybeType<AnyType>> // helper for brevity
type GetMaybeConstructors<AnyType extends Maybe_<AnyType>> = AnyType['val']['type']
type CallBack<AnyType_0, AnyType_1> = (value: AnyType_0) => AnyType_1
type Match<AnyType extends Maybe_<AnyType>> = {
[Constructor in GetMaybeConstructors<AnyType>]: CallBack< InferMaybeType<AnyType>, unknown >
}
// *** second and final pass ****
type InferMaybeType<AnyType_0> = AnyType_0 extends Maybe<infer AnyType_1> ? AnyType_1 : never
type Maybe_<MaybeType> = Maybe<InferMaybeType<MaybeType>> // helper for brevity
type GetMaybeConstructors<MaybeType extends Maybe_<AnyType>> = MaybeType['val']['type']
type CallBack<AnyType_0, AnyType_1> = (value: AnyType_0) => AnyType_1
type Match<MaybeType extends Maybe_<MaybeType>> = {
[Constructor in GetMaybeConstructors<MaybeType>]: CallBack< InferMaybeType<MaybeType>, unknown >
}
// *** third pass --- ok lets try some 'ad hoc' improvement ****
type InferMaybeType<AnyType> = AnyType extends Maybe<infer MaybeType> ? MaybeType : never
type Maybe_<Type> = Maybe<InferMaybeType<Type>> // helper for brevity
type GetMaybeConstructors<MaybeType extends Maybe_<MaybeType>> = MaybeType['val']['type']
type CallBack<AnyType_0, AnyType_1> = (value: AnyType_0) => AnyType_1
type Match<MaybeType extends Maybe_<MaybeType>> = {
[Constructor in GetMaybeConstructors<MaybeType>]: CallBack< InferMaybeType<MaybeType>, unknown >
}
// *******************************************************
// Naming Based on underlying's Data Structure it conveys
// *******************************************************
type InferMaybeType<TElement> = TElement extends Maybe<infer TElementInfered> ? TElementInfered : never
type Type<TElement> = Maybe<InferMaybeType<TElement>> // helper for brevity
type GetMaybeConstructors<TMaybe extends Type<TMaybe>> = TMaybe['val']['type']
type CallBack<Argument, ReturnType_> = (value: Argument) => ReturnType_
type Match<TMaybe extends Type<TMaybe>> = {
[Constructor in GetMaybeConstructors<TMaybe>]: CallBack< InferMaybeType<TMaybe>, unknown >
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment