How do I express this in Typescript?

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


Good news: With TypeScript 2.1.0, this is now possible via Mapped Types:

type Option<T> = { map() => T };
type OptionsHash<T> = { [K in keyof T]: Option<T[K]> };
function optionsFor<T>(structure: T): OptionsHash<T> { ... };

let input = { foo: 5, bar: 'X' };
let output = optionsFor(input);
// output is now typed as { foo: { map: () => number }, bar: { map: () => string } }

The opposite is also possible:

function retreiveOptions<T>(hash: OptionsHash<T>): T { ... };

let optionsHash = {
    foo: { map() { return 5; } },
    bar: { map() { return 'x'; } }
};
let optionsObject = retreiveOptions(optionsHash);
// optionsObject is now typed as { foo: number, bar: string }