2
class A {
    public static readonly TYPE = "A";
}

interface forA {
    for: A.TYPE
}

As you can see, I'm trying to access A.TYPE from forA, so that I can do a form of type guarding.

But, I'm getting the error: TS2702: 'A' only refers to a type, but is being used as a namespace here.

Is there a work around for this?

Tobiq
  • 2,489
  • 19
  • 38
  • 1
    Use `A['TYPE']` (a [lookup type](https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#keyof-and-lookup-types)). – jcalz Mar 04 '19 at 01:58
  • @jcalz `TS2339: Property 'TYPE' does not exist on type 'A'` – Tobiq Mar 04 '19 at 02:04
  • Whoops didn't notice it was `static`. You want `(typeof A)['TYPE']` – jcalz Mar 04 '19 at 02:05
  • Do you know why (typeof A).TYPE doesn't work? – Tobiq Mar 04 '19 at 02:10
  • @Tobiq because `.` is not a valid operator for types. – zerkms Mar 04 '19 at 02:11
  • is something like this possible: `interface for { type: (typeof T)["TYPE"] }`? I get: `TS2693: 'T' only refers to a type, but is being used as a value here.` – Tobiq Mar 04 '19 at 02:12
  • No, [types and values are not the same](https://stackoverflow.com/a/50396312/2887218). You could do `interface forType { type: T['TYPE'] };` and then `type forA = forType`. – jcalz Mar 04 '19 at 02:46
  • Possible duplicate of [Is there a way to “extract” the type of TypeScript interface property?](https://stackoverflow.com/questions/36311284/is-there-a-way-to-extract-the-type-of-typescript-interface-property/) – jcalz Mar 04 '19 at 02:48
  • @jcalz with that example, I'd have to repeated used `typeof` which is not really helpful. I want it to be generic with the type, not this so called "value" – Tobiq Mar 04 '19 at 03:10
  • i.e: `interface forType { type: (typeof T)['TYPE'] };` – Tobiq Mar 04 '19 at 03:11
  • `type forClass = forType` doesn't work – Tobiq Mar 04 '19 at 03:21
  • @jcalz https://stackoverflow.com/questions/54976239/generic-type-guarding-with-typescript – Tobiq Mar 04 '19 at 03:32
  • You can't do `typeof T` if `T` is a type. You can only do `typeof v` where `v` is a value. The [answer I linked earlier](https://stackoverflow.com/questions/50376977/generic-type-to-get-enum-keys-as-union-string-in-typescript/50396312#50396312) is an explanation of this. Not sure how else to say this, sorry – jcalz Mar 04 '19 at 03:37

1 Answers1

3

The type you're looking for is (typeof A)['TYPE'] or typeof (A.TYPE).

For the (typeof A)['TYPE'] notation:

  • Static properties are properties of the class constructor, so you need to use typeof A instead of A. (The constructor is a value named A, which is not the same as the type A, despite the same name. So typeof A gives you the type of the constructor)

  • And you need bracket notation to look up a property at the key "TYPE". For whatever reason, TypeScript doesn't have . as a type operator (maybe it would conflict with some namespace notation?). So it is (typeof A)['TYPE'] and not (typeof A).TYPE.

For the typeof (A.TYPE) notation:

  • As mentioned above, there is a value named A which is the constructor for A class instances. That value has a property named TYPE. So there is a value named A.TYPE. The type of this value can be queried as typeof (A.TYPE). This is probably the easiest notation for what you're trying to do.

Okay, hope that helps; good luck!

jcalz
  • 264,269
  • 27
  • 359
  • 360