noInfer.ts(35,13): error TS2345: Argument of type '"bar"' is not assignable to parameter of type '"foo"'.
noInfer.ts(36,14): error TS2322: Type '"bar"' is not assignable to type '"foo"'.
noInfer.ts(37,14): error TS2322: Type '"bar"' is not assignable to type '"foo"'.
noInfer.ts(38,15): error TS2322: Type '"bar"' is not assignable to type '"foo"'.
noInfer.ts(39,15): error TS2322: Type '"bar"' is not assignable to type '"foo"'.
noInfer.ts(47,30): error TS2741: Property 'woof' is missing in type 'Animal' but required in type 'Dog'.
noInfer.ts(53,16): error TS2345: Argument of type '{ x: number; }' is not assignable to parameter of type '{ x: number; y: number; }'.
  Property 'y' is missing in type '{ x: number; }' but required in type '{ x: number; y: number; }'.
noInfer.ts(58,22): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.
noInfer.ts(59,14): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.
noInfer.ts(66,14): error TS2345: Argument of type '{}' is not assignable to parameter of type '{ foo: number; }'.
  Property 'foo' is missing in type '{}' but required in type '{ foo: number; }'.


==== noInfer.ts (10 errors) ====
    // NoInfer<T> is erased for primitives
    
    type T00 = NoInfer<string>;
    type T01 = NoInfer<string | number | boolean>;
    type T02 = NoInfer<undefined>;
    type T03 = NoInfer<"foo">;
    type T04 = NoInfer<`foo${string}`>;
    type T05 = NoInfer<`foo${string}` & `${string}bar`>;
    type T06 = NoInfer<{}>;
    
    // NoInfer<T> is preserved for object types
    
    type T10 = NoInfer<string[]>;
    type T11 = NoInfer<{ x: string }>;
    
    // NoInfer<T> is erased if it has no effect
    
    type T20<T> = NoInfer<NoInfer<T>>;
    type T21<T> = NoInfer<NoInfer<T> & string>;
    type T22<T> = NoInfer<NoInfer<T> & string[]>;
    
    // keyof NoInfer<T> is transformed into NoInfer<keyof T>
    
    type T30 = keyof NoInfer<{ a: string, b: string }>;
    type T31<T> = keyof NoInfer<T>;
    type T32 = { [K in keyof NoInfer<{ a: string, b: string }>]: K };
    
    declare function foo1<T extends string>(a: T, b: NoInfer<T>): void
    declare function foo2<T extends string>(a: T, b: NoInfer<T>[]): void
    declare function foo3<T extends string>(a: T, b: NoInfer<T[]>): void
    declare function foo4<T extends string>(a: T, b: { x: NoInfer<T> }): void
    declare function foo5<T extends string>(a: T, b: NoInfer<{ x: T }>): void
    
    foo1('foo', 'foo') // ok
    foo1('foo', 'bar') // error
                ~~~~~
!!! error TS2345: Argument of type '"bar"' is not assignable to parameter of type '"foo"'.
    foo2('foo', ['bar']) // error
                 ~~~~~
!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'.
    foo3('foo', ['bar']) // error
                 ~~~~~
!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'.
    foo4('foo', { x: 'bar' }) // error
                  ~
!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'.
!!! related TS6500 noInfer.ts:31:52: The expected type comes from property 'x' which is declared here on type '{ x: "foo"; }'
    foo5('foo', { x: 'bar' }) // error
                  ~
!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'.
!!! related TS6500 noInfer.ts:32:60: The expected type comes from property 'x' which is declared here on type 'NoInfer<{ x: "foo"; }>'
    
    declare class Animal { move(): void }
    declare class Dog extends Animal { woof(): void }
    declare function doSomething<T>(value: T, getDefault: () => NoInfer<T>): void;
    
    doSomething(new Animal(), () => new Animal()); // ok
    doSomething(new Animal(), () => new Dog()); // ok
    doSomething(new Dog(), () => new Animal()); // error
                                 ~~~~~~~~~~~~
!!! error TS2741: Property 'woof' is missing in type 'Animal' but required in type 'Dog'.
!!! related TS2728 noInfer.ts:42:36: 'woof' is declared here.
!!! related TS6502 noInfer.ts:43:55: The expected type comes from the return type of this signature.
    
    declare function assertEqual<T>(actual: T, expected: NoInfer<T>): boolean;
    
    assertEqual({ x: 1 }, { x: 3 }); // ok
    const g = { x: 3, y: 2 };
    assertEqual(g, { x: 3 }); // error
                   ~~~~~~~~
!!! error TS2345: Argument of type '{ x: number; }' is not assignable to parameter of type '{ x: number; y: number; }'.
!!! error TS2345:   Property 'y' is missing in type '{ x: number; }' but required in type '{ x: number; y: number; }'.
!!! related TS2728 noInfer.ts:52:19: 'y' is declared here.
    
    declare function invoke<T, R>(func: (value: T) => R, value: NoInfer<T>): R;
    declare function test(value: { x: number; }): number;
    
    invoke(test, { x: 1, y: 2 }); // error
                         ~
!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.
    test({ x: 1, y: 2 }); // error
                 ~
!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.
    
    type Component<Props> = { props: Props; };
    declare function doWork<Props>(Component: Component<Props>, props: NoInfer<Props>): void;
    declare const comp: Component<{ foo: number }>;
    
    doWork(comp, { foo: 42 }); // ok
    doWork(comp, {}); // error
                 ~~
!!! error TS2345: Argument of type '{}' is not assignable to parameter of type '{ foo: number; }'.
!!! error TS2345:   Property 'foo' is missing in type '{}' but required in type '{ foo: number; }'.
!!! related TS2728 noInfer.ts:63:33: 'foo' is declared here.
    
    declare function mutate<T>(callback: (a: NoInfer<T>, b: number) => T): T;
    const mutate1 = mutate((a, b) => b);
    
    declare class ExampleClass<T> {}
    class OkClass<T> {
        constructor(private clazz: ExampleClass<T>, private _value: NoInfer<T>) {}
    
        get value(): T {
            return this._value; // ok
        }
    }
    class OkClass2<T> {
        constructor(private clazz: ExampleClass<T>, public _value: NoInfer<T>) {}
    }
    