Skip to content

Commit b25bf3e

Browse files
committed
Add tests
1 parent 411205e commit b25bf3e

File tree

5 files changed

+975
-0
lines changed

5 files changed

+975
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
noInfer.ts(29,13): error TS2345: Argument of type '"bar"' is not assignable to parameter of type '"foo"'.
2+
noInfer.ts(30,14): error TS2322: Type '"bar"' is not assignable to type '"foo"'.
3+
noInfer.ts(31,14): error TS2322: Type '"bar"' is not assignable to type '"foo"'.
4+
noInfer.ts(32,15): error TS2322: Type '"bar"' is not assignable to type '"foo"'.
5+
noInfer.ts(33,15): error TS2322: Type '"bar"' is not assignable to type '"foo"'.
6+
noInfer.ts(41,30): error TS2741: Property 'woof' is missing in type 'Animal' but required in type 'Dog'.
7+
noInfer.ts(47,16): error TS2345: Argument of type '{ x: number; }' is not assignable to parameter of type '{ x: number; y: number; }'.
8+
Property 'y' is missing in type '{ x: number; }' but required in type '{ x: number; y: number; }'.
9+
noInfer.ts(52,22): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.
10+
noInfer.ts(53,14): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.
11+
noInfer.ts(60,14): error TS2345: Argument of type '{}' is not assignable to parameter of type '{ foo: number; }'.
12+
Property 'foo' is missing in type '{}' but required in type '{ foo: number; }'.
13+
14+
15+
==== noInfer.ts (10 errors) ====
16+
// NoInfer<T> is erased for primitives
17+
18+
type T00 = NoInfer<string>;
19+
type T01 = NoInfer<string | number | boolean>;
20+
type T02 = NoInfer<undefined>;
21+
type T03 = NoInfer<"foo">;
22+
type T04 = NoInfer<`foo${string}`>;
23+
type T05 = NoInfer<`foo${string}` & `${string}bar`>;
24+
type T06 = NoInfer<{}>;
25+
26+
// NoInfer<T> is preserved for object types
27+
28+
type T10 = NoInfer<string[]>;
29+
type T11 = NoInfer<{ x: string }>;
30+
31+
// NoInfer<T> is erased if it has no effect
32+
33+
type T20<T> = NoInfer<NoInfer<T>>;
34+
type T21<T> = NoInfer<NoInfer<T> & string>;
35+
type T22<T> = NoInfer<NoInfer<T> & string[]>;
36+
37+
declare function foo1<T extends string>(a: T, b: NoInfer<T>): void
38+
declare function foo2<T extends string>(a: T, b: NoInfer<T>[]): void
39+
declare function foo3<T extends string>(a: T, b: NoInfer<T[]>): void
40+
declare function foo4<T extends string>(a: T, b: { x: NoInfer<T> }): void
41+
declare function foo5<T extends string>(a: T, b: NoInfer<{ x: T }>): void
42+
43+
foo1('foo', 'foo') // ok
44+
foo1('foo', 'bar') // error
45+
~~~~~
46+
!!! error TS2345: Argument of type '"bar"' is not assignable to parameter of type '"foo"'.
47+
foo2('foo', ['bar']) // error
48+
~~~~~
49+
!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'.
50+
foo3('foo', ['bar']) // error
51+
~~~~~
52+
!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'.
53+
foo4('foo', { x: 'bar' }) // error
54+
~
55+
!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'.
56+
!!! related TS6500 noInfer.ts:25:52: The expected type comes from property 'x' which is declared here on type '{ x: "foo"; }'
57+
foo5('foo', { x: 'bar' }) // error
58+
~
59+
!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'.
60+
!!! related TS6500 noInfer.ts:26:60: The expected type comes from property 'x' which is declared here on type 'NoInfer<{ x: "foo"; }>'
61+
62+
declare class Animal { move(): void }
63+
declare class Dog extends Animal { woof(): void }
64+
declare function doSomething<T>(value: T, getDefault: () => NoInfer<T>): void;
65+
66+
doSomething(new Animal(), () => new Animal()); // ok
67+
doSomething(new Animal(), () => new Dog()); // ok
68+
doSomething(new Dog(), () => new Animal()); // error
69+
~~~~~~~~~~~~
70+
!!! error TS2741: Property 'woof' is missing in type 'Animal' but required in type 'Dog'.
71+
!!! related TS2728 noInfer.ts:36:36: 'woof' is declared here.
72+
!!! related TS6502 noInfer.ts:37:55: The expected type comes from the return type of this signature.
73+
74+
declare function assertEqual<T>(actual: T, expected: NoInfer<T>): boolean;
75+
76+
assertEqual({ x: 1 }, { x: 3 }); // ok
77+
const g = { x: 3, y: 2 };
78+
assertEqual(g, { x: 3 }); // error
79+
~~~~~~~~
80+
!!! error TS2345: Argument of type '{ x: number; }' is not assignable to parameter of type '{ x: number; y: number; }'.
81+
!!! error TS2345: Property 'y' is missing in type '{ x: number; }' but required in type '{ x: number; y: number; }'.
82+
!!! related TS2728 noInfer.ts:46:19: 'y' is declared here.
83+
84+
declare function invoke<T, R>(func: (value: T) => R, value: NoInfer<T>): R;
85+
declare function test(value: { x: number; }): number;
86+
87+
invoke(test, { x: 1, y: 2 }); // error
88+
~
89+
!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.
90+
test({ x: 1, y: 2 }); // error
91+
~
92+
!!! error TS2353: Object literal may only specify known properties, and 'y' does not exist in type '{ x: number; }'.
93+
94+
type Component<Props> = { props: Props; };
95+
declare function doWork<Props>(Component: Component<Props>, props: NoInfer<Props>): void;
96+
declare const comp: Component<{ foo: number }>;
97+
98+
doWork(comp, { foo: 42 }); // ok
99+
doWork(comp, {}); // error
100+
~~
101+
!!! error TS2345: Argument of type '{}' is not assignable to parameter of type '{ foo: number; }'.
102+
!!! error TS2345: Property 'foo' is missing in type '{}' but required in type '{ foo: number; }'.
103+
!!! related TS2728 noInfer.ts:57:33: 'foo' is declared here.
104+
105+
declare function mutate<T>(callback: (a: NoInfer<T>, b: number) => T): T;
106+
const mutate1 = mutate((a, b) => b);
107+
108+
declare class ExampleClass<T> {}
109+
class OkClass<T> {
110+
constructor(private clazz: ExampleClass<T>, private _value: NoInfer<T>) {}
111+
112+
get value(): T {
113+
return this._value; // ok
114+
}
115+
}
116+
class OkClass2<T> {
117+
constructor(private clazz: ExampleClass<T>, public _value: NoInfer<T>) {}
118+
}
119+

tests/baselines/reference/noInfer.js

+185
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
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

Comments
 (0)