1

Suppose I have the following code snippet:

interface Generic <S, T> {
    _?: [S, T];
    id: string;
    ...
}

interface A {}
interface B {}
interface C {}
interface D {}

type t1 = Generic<A, B>;
type t2 = Generic<B, C>;

This is code that I cannot change (from another package). My question is: is there a way for me to find out programatically what are S and T for a given type (e.g. t1, t2)?

I have a strong suspicion that since this information is lost after compilation, I will never be able to figure out what S and T are at runtime. Even worst, I won't be able to look at details from t1 and t2 (just like this previous question).

However, since I'm very new to TypeScript, I wonder if I just didn't know the right way to ask, and the internet actually has an answer for me.

So, is it possible? How?

jumattos
  • 11
  • 3
  • Do note that `t1` and `t2` are exactly the same type, since `A`, `B`, `C`, and `D` are identical empty interfaces. The TypeScript type system is [structural](https://github.com/Microsoft/TypeScript/wiki/FAQ#what-is-structural-typing), not nominal. Two types are equivalent if and only if they have the same *structure*, not the same *name*. This will lead to [weird behavior](https://github.com/Microsoft/TypeScript/wiki/FAQ#why-do-these-empty-classes-behave-strangely), so I'd suggest that (even in demo types like you have above) you add some differing properties to distinguish them. – jcalz Mar 20 '19 at 00:20

1 Answers1

0

You are correct that as the TypeScript types are erased at runtime you cannot access them then. However, you are able to access the types of the generic parameters at compile time using conditional types:

type FirstOfGeneric<G> = G extends Generic<infer F, any> ? F : never;
type SecondOfGeneric<G> = G extends Generic<any, infer S> ? S : never;

// type t1_f = A
type t1_f = FirstOfGeneric<t1>;
// type t1_s = B
type t1_s = SecondOfGeneric<t1>;

You can then use standard TS features like typeguards and casting to act upon the runtime instances of t1_f and t1_s,

y2bd
  • 5,783
  • 1
  • 22
  • 25