|
| 1 | +//// [tests/cases/conformance/types/typeRelationships/typeInference/noInfer.ts] //// |
| 2 | + |
| 3 | +//// [noInfer.ts] |
| 4 | +// NoInfer<T> is erased for primitives |
| 5 | + |
| 6 | +type T00 = NoInfer<string>; |
| 7 | +type T01 = NoInfer<string | number | boolean>; |
| 8 | +type T02 = NoInfer<undefined>; |
| 9 | +type T03 = NoInfer<"foo">; |
| 10 | +type T04 = NoInfer<`foo${string}`>; |
| 11 | +type T05 = NoInfer<`foo${string}` & `${string}bar`>; |
| 12 | +type T06 = NoInfer<{}>; |
| 13 | + |
| 14 | +// NoInfer<T> is preserved for object types |
| 15 | + |
| 16 | +type T10 = NoInfer<string[]>; |
| 17 | +type T11 = NoInfer<{ x: string }>; |
| 18 | + |
| 19 | +// NoInfer<T> is erased if it has no effect |
| 20 | + |
| 21 | +type T20<T> = NoInfer<NoInfer<T>>; |
| 22 | +type T21<T> = NoInfer<NoInfer<T> & string>; |
| 23 | +type T22<T> = NoInfer<NoInfer<T> & string[]>; |
| 24 | + |
| 25 | +declare function foo1<T extends string>(a: T, b: NoInfer<T>): void |
| 26 | +declare function foo2<T extends string>(a: T, b: NoInfer<T>[]): void |
| 27 | +declare function foo3<T extends string>(a: T, b: NoInfer<T[]>): void |
| 28 | +declare function foo4<T extends string>(a: T, b: { x: NoInfer<T> }): void |
| 29 | +declare function foo5<T extends string>(a: T, b: NoInfer<{ x: T }>): void |
| 30 | + |
| 31 | +foo1('foo', 'foo') // ok |
| 32 | +foo1('foo', 'bar') // error |
| 33 | +foo2('foo', ['bar']) // error |
| 34 | +foo3('foo', ['bar']) // error |
| 35 | +foo4('foo', { x: 'bar' }) // error |
| 36 | +foo5('foo', { x: 'bar' }) // error |
| 37 | + |
| 38 | +declare class Animal { move(): void } |
| 39 | +declare class Dog extends Animal { woof(): void } |
| 40 | +declare function doSomething<T>(value: T, getDefault: () => NoInfer<T>): void; |
| 41 | + |
| 42 | +doSomething(new Animal(), () => new Animal()); // ok |
| 43 | +doSomething(new Animal(), () => new Dog()); // ok |
| 44 | +doSomething(new Dog(), () => new Animal()); // error |
| 45 | + |
| 46 | +declare function assertEqual<T>(actual: T, expected: NoInfer<T>): boolean; |
| 47 | + |
| 48 | +assertEqual({ x: 1 }, { x: 3 }); // ok |
| 49 | +const g = { x: 3, y: 2 }; |
| 50 | +assertEqual(g, { x: 3 }); // error |
| 51 | + |
| 52 | +declare function invoke<T, R>(func: (value: T) => R, value: NoInfer<T>): R; |
| 53 | +declare function test(value: { x: number; }): number; |
| 54 | + |
| 55 | +invoke(test, { x: 1, y: 2 }); // error |
| 56 | +test({ x: 1, y: 2 }); // error |
| 57 | + |
| 58 | +type Component<Props> = { props: Props; }; |
| 59 | +declare function doWork<Props>(Component: Component<Props>, props: NoInfer<Props>): void; |
| 60 | +declare const comp: Component<{ foo: number }>; |
| 61 | + |
| 62 | +doWork(comp, { foo: 42 }); // ok |
| 63 | +doWork(comp, {}); // error |
| 64 | + |
| 65 | +declare function mutate<T>(callback: (a: NoInfer<T>, b: number) => T): T; |
| 66 | +const mutate1 = mutate((a, b) => b); |
| 67 | + |
| 68 | +declare class ExampleClass<T> {} |
| 69 | +class OkClass<T> { |
| 70 | + constructor(private clazz: ExampleClass<T>, private _value: NoInfer<T>) {} |
| 71 | + |
| 72 | + get value(): T { |
| 73 | + return this._value; // ok |
| 74 | + } |
| 75 | +} |
| 76 | +class OkClass2<T> { |
| 77 | + constructor(private clazz: ExampleClass<T>, public _value: NoInfer<T>) {} |
| 78 | +} |
| 79 | + |
| 80 | + |
| 81 | +//// [noInfer.js] |
| 82 | +"use strict"; |
| 83 | +// NoInfer<T> is erased for primitives |
| 84 | +foo1('foo', 'foo'); // ok |
| 85 | +foo1('foo', 'bar'); // error |
| 86 | +foo2('foo', ['bar']); // error |
| 87 | +foo3('foo', ['bar']); // error |
| 88 | +foo4('foo', { x: 'bar' }); // error |
| 89 | +foo5('foo', { x: 'bar' }); // error |
| 90 | +doSomething(new Animal(), function () { return new Animal(); }); // ok |
| 91 | +doSomething(new Animal(), function () { return new Dog(); }); // ok |
| 92 | +doSomething(new Dog(), function () { return new Animal(); }); // error |
| 93 | +assertEqual({ x: 1 }, { x: 3 }); // ok |
| 94 | +var g = { x: 3, y: 2 }; |
| 95 | +assertEqual(g, { x: 3 }); // error |
| 96 | +invoke(test, { x: 1, y: 2 }); // error |
| 97 | +test({ x: 1, y: 2 }); // error |
| 98 | +doWork(comp, { foo: 42 }); // ok |
| 99 | +doWork(comp, {}); // error |
| 100 | +var mutate1 = mutate(function (a, b) { return b; }); |
| 101 | +var OkClass = /** @class */ (function () { |
| 102 | + function OkClass(clazz, _value) { |
| 103 | + this.clazz = clazz; |
| 104 | + this._value = _value; |
| 105 | + } |
| 106 | + Object.defineProperty(OkClass.prototype, "value", { |
| 107 | + get: function () { |
| 108 | + return this._value; // ok |
| 109 | + }, |
| 110 | + enumerable: false, |
| 111 | + configurable: true |
| 112 | + }); |
| 113 | + return OkClass; |
| 114 | +}()); |
| 115 | +var OkClass2 = /** @class */ (function () { |
| 116 | + function OkClass2(clazz, _value) { |
| 117 | + this.clazz = clazz; |
| 118 | + this._value = _value; |
| 119 | + } |
| 120 | + return OkClass2; |
| 121 | +}()); |
| 122 | + |
| 123 | + |
| 124 | +//// [noInfer.d.ts] |
| 125 | +type T00 = NoInfer<string>; |
| 126 | +type T01 = NoInfer<string | number | boolean>; |
| 127 | +type T02 = NoInfer<undefined>; |
| 128 | +type T03 = NoInfer<"foo">; |
| 129 | +type T04 = NoInfer<`foo${string}`>; |
| 130 | +type T05 = NoInfer<`foo${string}` & `${string}bar`>; |
| 131 | +type T06 = NoInfer<{}>; |
| 132 | +type T10 = NoInfer<string[]>; |
| 133 | +type T11 = NoInfer<{ |
| 134 | + x: string; |
| 135 | +}>; |
| 136 | +type T20<T> = NoInfer<NoInfer<T>>; |
| 137 | +type T21<T> = NoInfer<NoInfer<T> & string>; |
| 138 | +type T22<T> = NoInfer<NoInfer<T> & string[]>; |
| 139 | +declare function foo1<T extends string>(a: T, b: NoInfer<T>): void; |
| 140 | +declare function foo2<T extends string>(a: T, b: NoInfer<T>[]): void; |
| 141 | +declare function foo3<T extends string>(a: T, b: NoInfer<T[]>): void; |
| 142 | +declare function foo4<T extends string>(a: T, b: { |
| 143 | + x: NoInfer<T>; |
| 144 | +}): void; |
| 145 | +declare function foo5<T extends string>(a: T, b: NoInfer<{ |
| 146 | + x: T; |
| 147 | +}>): void; |
| 148 | +declare class Animal { |
| 149 | + move(): void; |
| 150 | +} |
| 151 | +declare class Dog extends Animal { |
| 152 | + woof(): void; |
| 153 | +} |
| 154 | +declare function doSomething<T>(value: T, getDefault: () => NoInfer<T>): void; |
| 155 | +declare function assertEqual<T>(actual: T, expected: NoInfer<T>): boolean; |
| 156 | +declare const g: { |
| 157 | + x: number; |
| 158 | + y: number; |
| 159 | +}; |
| 160 | +declare function invoke<T, R>(func: (value: T) => R, value: NoInfer<T>): R; |
| 161 | +declare function test(value: { |
| 162 | + x: number; |
| 163 | +}): number; |
| 164 | +type Component<Props> = { |
| 165 | + props: Props; |
| 166 | +}; |
| 167 | +declare function doWork<Props>(Component: Component<Props>, props: NoInfer<Props>): void; |
| 168 | +declare const comp: Component<{ |
| 169 | + foo: number; |
| 170 | +}>; |
| 171 | +declare function mutate<T>(callback: (a: NoInfer<T>, b: number) => T): T; |
| 172 | +declare const mutate1: unknown; |
| 173 | +declare class ExampleClass<T> { |
| 174 | +} |
| 175 | +declare class OkClass<T> { |
| 176 | + private clazz; |
| 177 | + private _value; |
| 178 | + constructor(clazz: ExampleClass<T>, _value: NoInfer<T>); |
| 179 | + get value(): T; |
| 180 | +} |
| 181 | +declare class OkClass2<T> { |
| 182 | + private clazz; |
| 183 | + _value: NoInfer<T>; |
| 184 | + constructor(clazz: ExampleClass<T>, _value: NoInfer<T>); |
| 185 | +} |
0 commit comments