Skip to content

Instantly share code, notes, and snippets.

@lumie1337
Last active November 8, 2018 22:32
Show Gist options
  • Save lumie1337/3e49fe857fda2d20b509571a9d383f17 to your computer and use it in GitHub Desktop.
Save lumie1337/3e49fe857fda2d20b509571a9d383f17 to your computer and use it in GitHub Desktop.
// 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