tests/cases/compiler/conditionalTypeDoesntSpinForever.ts(23,15): error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
tests/cases/compiler/conditionalTypeDoesntSpinForever.ts(36,19): error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
tests/cases/compiler/conditionalTypeDoesntSpinForever.ts(53,21): error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
tests/cases/compiler/conditionalTypeDoesntSpinForever.ts(53,45): error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
tests/cases/compiler/conditionalTypeDoesntSpinForever.ts(65,17): error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
tests/cases/compiler/conditionalTypeDoesntSpinForever.ts(78,38): error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
tests/cases/compiler/conditionalTypeDoesntSpinForever.ts(94,21): error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
tests/cases/compiler/conditionalTypeDoesntSpinForever.ts(97,71): error TS2322: Type 'SO_FAR' is not assignable to type 'object'.


==== tests/cases/compiler/conditionalTypeDoesntSpinForever.ts (8 errors) ====
    // A *self-contained* demonstration of the problem follows...
    // Test this by running `tsc --target es6` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.
    
    export enum PubSubRecordIsStoredInRedisAsA {
        redisHash = "redisHash",
        jsonEncodedRedisString = "jsonEncodedRedisString"
      }
      
      export interface PubSubRecord<NAME extends string, RECORD, IDENTIFIER extends Partial<RECORD>> {
        name: NAME;
        record: RECORD;
        identifier: IDENTIFIER;
        storedAs: PubSubRecordIsStoredInRedisAsA;
        maxMsToWaitBeforePublishing: number;
      }
      
      type NameFieldConstructor<SO_FAR> =
        SO_FAR extends {name: any} ? {} : {
          name: <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {name: TYPE}>
        }
      
      const buildNameFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
        "name" in soFar ? {} : {
                  ~~~~~
!!! error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
!!! related TS2208 tests/cases/compiler/conditionalTypeDoesntSpinForever.ts:22:38: This type parameter might need an `extends object` constraint.
          name: <TYPE>(instance: TYPE = undefined) =>
            buildPubSubRecordType(Object.assign({}, soFar, {name: instance as TYPE}) as SO_FAR & {name: TYPE}) as BuildPubSubRecordType<SO_FAR & {name: TYPE}>
        }
      );
      
      type StoredAsConstructor<SO_FAR> =
        SO_FAR extends {storedAs: any} ? {} : {
          storedAsJsonEncodedRedisString: () => BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>;
          storedRedisHash: () => BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>;
        }
      
      const buildStoredAsConstructor = <SO_FAR>(soFar: SO_FAR) => (
        "storedAs" in soFar ? {} : {
                      ~~~~~
!!! error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
!!! related TS2208 tests/cases/compiler/conditionalTypeDoesntSpinForever.ts:35:37: This type parameter might need an `extends object` constraint.
          storedAsJsonEncodedRedisString: () =>
            buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString})) as
              BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.jsonEncodedRedisString}>,
          storedAsRedisHash: () =>
            buildPubSubRecordType(Object.assign({}, soFar, {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash})) as
              BuildPubSubRecordType<SO_FAR & {storedAs: PubSubRecordIsStoredInRedisAsA.redisHash}>,
        }
      );
      
      type IdentifierFieldConstructor<SO_FAR> =
        SO_FAR extends {identifier: any} ? {} :
        SO_FAR extends {record: any} ? {
          identifier: <TYPE extends Partial<SO_FAR["record"]>>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {identifier: TYPE}>
        } : {}
      
      const buildIdentifierFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
        "identifier" in soFar || (!("record" in soFar)) ? {} : {
                        ~~~~~
!!! error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
!!! related TS2208 tests/cases/compiler/conditionalTypeDoesntSpinForever.ts:52:44: This type parameter might need an `extends object` constraint.
                                                ~~~~~
!!! error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
!!! related TS2208 tests/cases/compiler/conditionalTypeDoesntSpinForever.ts:52:44: This type parameter might need an `extends object` constraint.
          identifier: <TYPE>(instance: TYPE = undefined) =>
            buildPubSubRecordType(Object.assign({}, soFar, {identifier: instance as TYPE}) as SO_FAR & {identifier: TYPE}) as BuildPubSubRecordType<SO_FAR & {identifier: TYPE}>
        }
      );
      
      type RecordFieldConstructor<SO_FAR> =
        SO_FAR extends {record: any} ? {} : {
          record: <TYPE>(t?: TYPE) => BuildPubSubRecordType<SO_FAR & {record: TYPE}>
        }
      
      const buildRecordFieldConstructor = <SO_FAR>(soFar: SO_FAR) => (
        "record" in soFar ? {} : {
                    ~~~~~
!!! error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
!!! related TS2208 tests/cases/compiler/conditionalTypeDoesntSpinForever.ts:64:40: This type parameter might need an `extends object` constraint.
          record: <TYPE>(instance: TYPE = undefined) =>
            buildPubSubRecordType(Object.assign({}, soFar, {record: instance as TYPE}) as SO_FAR & {record: TYPE}) as BuildPubSubRecordType<SO_FAR & {record: TYPE}>
        }
      );
      
      type MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> =
        SO_FAR extends {maxMsToWaitBeforePublishing: any} ? {} : {
          maxMsToWaitBeforePublishing: (t: number) => BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>,
          neverDelayPublishing: () => BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>,
        }
      
      const buildMaxMsToWaitBeforePublishingFieldConstructor = <SO_FAR>(soFar: SO_FAR): MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> => (
        "maxMsToWaitBeforePublishing" in soFar ? {} : {
                                         ~~~~~
!!! error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
!!! related TS2208 tests/cases/compiler/conditionalTypeDoesntSpinForever.ts:77:61: This type parameter might need an `extends object` constraint.
          maxMsToWaitBeforePublishing: (instance: number = 0) =>
            buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: instance})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: number}>,
          neverDelayPublishing: () =>
            buildPubSubRecordType(Object.assign({}, soFar, {maxMsToWaitBeforePublishing: 0})) as BuildPubSubRecordType<SO_FAR & {maxMsToWaitBeforePublishing: 0}>,
        }
      ) as MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR>;
      
      type TypeConstructor<SO_FAR> =
        SO_FAR extends {identifier: any, record: any, maxMsToWaitBeforePublishing: number, storedAs: PubSubRecordIsStoredInRedisAsA} ? {
          type: SO_FAR,
          fields: Set<keyof SO_FAR>,
          hasField: (fieldName: string | number | symbol) => fieldName is keyof SO_FAR
        } : {}
      
      const buildType = <SO_FAR>(soFar: SO_FAR) => (
        "identifier" in soFar && "object" in soFar && "maxMsToWaitBeforePublishing" in soFar && "PubSubRecordIsStoredInRedisAsA" in soFar ? {} : {
                        ~~~~~
!!! error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
!!! related TS2208 tests/cases/compiler/conditionalTypeDoesntSpinForever.ts:93:22: This type parameter might need an `extends object` constraint.
          type: soFar,
          fields: () => new Set(Object.keys(soFar) as (keyof SO_FAR)[]),
          hasField: (fieldName: string | number | symbol) => fieldName in soFar
                                                                          ~~~~~
!!! error TS2322: Type 'SO_FAR' is not assignable to type 'object'.
!!! related TS2208 tests/cases/compiler/conditionalTypeDoesntSpinForever.ts:93:22: This type parameter might need an `extends object` constraint.
        }
      );
      
      type BuildPubSubRecordType<SO_FAR> =
        NameFieldConstructor<SO_FAR> &
        IdentifierFieldConstructor<SO_FAR> &
        RecordFieldConstructor<SO_FAR> &
        StoredAsConstructor<SO_FAR> & // infinite loop goes away when you comment out this line
        MaxMsToWaitBeforePublishingFieldConstructor<SO_FAR> &
        TypeConstructor<SO_FAR>
      
      const buildPubSubRecordType = <SO_FAR>(soFar: SO_FAR) => Object.assign(
        {},
        buildNameFieldConstructor(soFar),
        buildIdentifierFieldConstructor(soFar),
        buildRecordFieldConstructor(soFar),
        buildStoredAsConstructor(soFar),
        buildMaxMsToWaitBeforePublishingFieldConstructor(soFar),
        buildType(soFar)
      ) as BuildPubSubRecordType<SO_FAR>;
      const PubSubRecordType = buildPubSubRecordType({});