Last active
March 5, 2019 06:11
-
-
Save fvilante/992f3baa04745c9edf3d5d4586f020b4 to your computer and use it in GitHub Desktop.
Comparisson of alternative type parameter naming in Typescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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