// @flow

type A = A;
//   ^?
type B = B | null;
//   ^?
type C = A;
//   ^?
type D = { x: number };
//   ^?
type E = $Exact<D>;
//   ^?
type F = ?D;
//   ^?

type P<T: string> = { t: T } | boolean;
declare var a: P<string>;
if (typeof a !== "boolean") {
//         ^?
     a;
//   ^?
}

function f<X>() {
  type A = X;
  //   ^?
  type B = B | null;
  //   ^?
  type C = A;
  //   ^?
  type D = { x: X };
  //   ^?
  type E = $Exact<X>;
  //   ^?
  type F = ?X;
  //   ^?
}

type G<X> = X | null;
type H = G<number>;
//   ^?
type I = G<G<number> | string>
//   ^?
type J<X> = (<X>(x: X) => void) | X | null;
type K = J<number>;
//   ^?
type L<X, Y> = (<X>(x: X, y: Y) => void) | X | Y | null;
type M<Z> = L<number, Z>;
//   ^?
type N<A> = { x: N<A> } | null;
type O = N<number>
//   ^?

class Klass {};
type TKlass = typeof Klass;
//    ^?

declare function poly_id<T>(v: T): T;
type TypeOfWithTArgs = typeof poly_id<string>;
//             ^?
