Let's say I have an interface A
:
interface A {
foo: number
bar: string
}
And I have a generic type Option
:
type Option<T> = {
map: () => T
}
Then I create a new interface B
from A
and Option
:
interface B {
foo: Option<number>
bar: Option<string>
}
How can I make this operation more general? Ie. The API I want is:
type B = Lift<A>
Where Lift
automatically maps each member of A
to an Option
. Note that A
can have any number of members, of any type.
How can I implement Lift
? If this is not possible in TypeScript, does anyone have a Scala/Haskell solution?
You are looking for higher-kinded types. Here it is in Scala:
trait FooBar[M[_]] {
val foo: M[Integer]
val bar: M[String]
}
type Identity[X] = X
type A = FooBar[Identity]
type B = FooBar[Option]
You can use any second-order types e.g.:
type C = FooBar[List]
But these will not compile:
// type S = FooBar[String] ---> String is a first-order type
// type M = FooBar[Map] ---> Map[K, V] is a third-order type
Unfortunately, this has not yet made it into TypeScript but there is an open issue for it: https://github.com/Microsoft/TypeScript/issues/1213
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With