Last active
November 8, 2018 22:32
-
-
Save lumie1337/3e49fe857fda2d20b509571a9d383f17 to your computer and use it in GitHub Desktop.
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
// lets suppose | |
type F<T> = [T] // Note: this does not support any mapped types here, more specifically we can NOT test T for any types as we have placeholders in there | |
// instead of writing this | |
class HasGeneric<A, B = F<A>, C = F<B>, D = F<C>> { | |
useA: A | |
useB: B | |
useC: B | |
useD: B | |
} | |
// we can pull out the definition into something like this | |
type HasGeneric2Defaults = { | |
0: RequiredArgument, | |
1: F<ArgumentReference<0>>, | |
2: F<ArgumentReference<1>>, | |
3: F<ArgumentReference<2>> | |
} | |
// GenericArguments<HasGeneric2Defaults> expands to [any] | [any, any] | [any, any, any] | [any, any, any, any] (as in 1-4 parameters) | |
class HasGeneric2<T extends GenericArguments<HasGeneric2Defaults>> { | |
useA: LookupGeneric<T, HasGeneric2Defaults, 0> // looks up argument 1 | |
useB: LookupGeneric<T, HasGeneric2Defaults, 1> // looks up argument 2 | |
useC: LookupGeneric<T, HasGeneric2Defaults, 2> // looks up argument 3 | |
useD: LookupGeneric<T, HasGeneric2Defaults, 3> // looks up argument 4 | |
} | |
// example use | |
const example1 = new HasGeneric2<[string]>() // sets A = string | |
const useA: string = example1.useA | |
const useB: [string] = example1.useB | |
const useC: [[string]] = example1.useC | |
const useD: [[[string]]] = example1.useD | |
const example1 = new HasGeneric2<[string, [string]]>() // sets A = string, B = [string] | |
class HasGeneric2_2<T extends GenericArguments<HasGeneric2Defaults>> { | |
private G: AllGenerics<T, HasGeneric2Defaults>; | |
useA: HasGeneric2_2<T>["G"][0] | |
useB: HasGeneric2_2<T>["G"][1] | |
useC: HasGeneric2_2<T>["G"][2] | |
useD: HasGeneric2_2<T>["G"][3] | |
} | |
type HasGeneric3Defaults = { | |
0: RequiredArgument<"A">, | |
1: OptionalArgument<"B", F<ArgumentReference<0>>>, | |
2: OptionalArgument<"C", F<ArgumentReference<1>>>, | |
3: OptionalArgument<"D", F<ArgumentReference<2>>> | |
} | |
class HasGeneric3<T extends GenericArguments<HasGeneric3Defaults>> { | |
private G: AllGenerics<T, HasGeneric3Defaults>; | |
useA: HasGeneric3<T>["G"].A | |
useB: HasGeneric3<T>["G"].B | |
useC: HasGeneric3<T>["G"].C | |
useD: HasGeneric3<T>["G"].D | |
} | |
// might be able to make the following work | |
class HasGeneric4<T extends GenericSpec<HasGeneric3Defaults>> { | |
useA: T["A"] | |
useB: T["B"] | |
useC: T["C"] | |
useD: T["D"] | |
} | |
const example2 = new HasGeneric4<BuildGeneric<HasGeneric3Defaults, [string]>> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment