/index.js(3,9): error TS7008: Member 'base' implicitly has an 'any' type.
/index.js(14,9): error TS7008: Member 'base' implicitly has an 'any' type.
/index.js(46,9): error TS7008: Member 'first' implicitly has an 'any' type.
/index.js(46,23): error TS7008: Member 'second' implicitly has an 'any' type.
/index.js(53,9): error TS7008: Member 'first' implicitly has an 'any' type.
/index.js(53,23): error TS7008: Member 'second' implicitly has an 'any' type.
/index.js(75,14): error TS2322: Type 'number' is not assignable to type 'string'.
/index.js(95,15): error TS2322: Type 'string' is not assignable to type 'number'.
/index.js(113,14): error TS2322: Type 'number' is not assignable to type 'string'.
/index.js(121,14): error TS2322: Type 'number' is not assignable to type 'string'.


==== /index.js (10 errors) ====
    export class C {
        constructor() {
            this.base = undefined;
            ~~~~~~~~~~~~~~~~~~~~~
!!! error TS7008: Member 'base' implicitly has an 'any' type.
            const nullableRead = this.base;
            /** @type {undefined} */
            const nullableCheck = nullableRead;
        }
    }
    
    export const nullableResult = new C().base;
    
    export const NullClass = class {
        constructor() {
            this.base = null;
            ~~~~~~~~~~~~~~~~
!!! error TS7008: Member 'base' implicitly has an 'any' type.
        }
    };
    
    export class LaterWrite {
        constructor() {
            this.base = undefined;
            this.base = 1;
        }
    }
    
    export class BranchWrite {
        /** @param {boolean} condition */
        constructor(condition) {
            this.base = undefined;
            if (condition) {
                this.base = 1;
            } else {
                this.base = "value";
            }
        }
    }
    
    export class Annotated {
        constructor() {
            /** @type {number | undefined} */
            this.base = undefined;
        }
    }
    
    export class MutualNestedNullable {
        constructor() {
            this.first = (this.second = undefined);
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS7008: Member 'first' implicitly has an 'any' type.
                          ~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS7008: Member 'second' implicitly has an 'any' type.
            this.second = (this.first = undefined);
        }
    }
    
    export const NestedNullableExpression = class {
        constructor() {
            this.first = (this.second = null);
            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS7008: Member 'first' implicitly has an 'any' type.
                          ~~~~~~~~~~~~~~~~~~
!!! error TS7008: Member 'second' implicitly has an 'any' type.
            this.second = (this.first = null);
        }
    };
    
    export const nestedNullableResult = new MutualNestedNullable().first;
    export const expressionNullableResult = new NestedNullableExpression().second;
    
    export class MutualNestedNumber {
        constructor() {
            this.first = (this.second = undefined);
            this.second = (this.first = undefined);
            this.first = 1;
            this.second = 2;
        }
    }
    
    /** @type {number} */
    export const nestedFirst = new MutualNestedNumber().first;
    /** @type {number} */
    export const nestedSecond = new MutualNestedNumber().second;
    /** @type {string} */
    export const invalidNestedString = new MutualNestedNumber().first;
                 ~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
    
    export class AssignmentValues {
        constructor() {
            const initialValue = (this.base = undefined);
            const initialRead = this.base;
            const numberValue = (this.base = 1);
            const stringValue = (this.base = "value");
            const finalRead = this.base;
            /** @type {undefined} */
            const initialCheck = initialValue;
            /** @type {undefined} */
            const initialReadCheck = initialRead;
            /** @type {number} */
            const numberCheck = numberValue;
            /** @type {string} */
            const stringCheck = stringValue;
            /** @type {string} */
            const finalReadCheck = finalRead;
            /** @type {number} */
            const invalidNumber = this.base;
                  ~~~~~~~~~~~~~
!!! error TS2322: Type 'string' is not assignable to type 'number'.
        }
    }
    
    export class Reentrant {
        constructor() {
            this.base = undefined;
            this.read = this.getValue();
            this.base = 1;
        }
        getValue() {
            return this.base;
        }
    }
    
    /** @type {number} */
    export const reentrantResult = new Reentrant().read;
    /** @type {string} */
    export const invalidReentrantString = new Reentrant().read;
                 ~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
    
    /** @type {string} */
    export const finalValue = new AssignmentValues().base;
    
    /** @type {number} */
    export const numberValue = new LaterWrite().base;
    /** @type {string} */
    export const invalidString = new LaterWrite().base;
                 ~~~~~~~~~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'string'.
    /** @type {number | string} */
    export const branchValue = new BranchWrite(true).base;