Skip to content

Commit 065c199

Browse files
committed
Add/modify tests
1 parent 93ef50e commit 065c199

6 files changed

Lines changed: 163 additions & 0 deletions
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// https://github.com/microsoft/TypeScript/issues/59937
5+
6+
type Ref<T> = {
7+
current: T;
8+
};
9+
10+
type FunctionComponent<P> = (props: P) => unknown;
11+
12+
type ComponentProps<T extends FunctionComponent<any>> =
13+
T extends FunctionComponent<infer P> ? P : {};
14+
15+
type PropsWithoutRef<P> = P extends any
16+
? "ref" extends keyof P
17+
? Omit<P, "ref">
18+
: P
19+
: P;
20+
21+
type ComponentPropsWithoutRef<T extends FunctionComponent<any>> =
22+
PropsWithoutRef<ComponentProps<T>>;
23+
24+
declare function forwardRef<T, P>(
25+
component: (props: P, ref: Ref<T>) => unknown,
26+
): (props: P & { ref?: Ref<T> }) => unknown;
27+
28+
const ComponentWithForwardRef = forwardRef(
29+
<T extends FunctionComponent<any>>(
30+
props: ComponentPropsWithoutRef<T>,
31+
ref: Ref<HTMLElement>,
32+
) => {
33+
return null;
34+
},
35+
);
36+
37+
type Test<T> = T extends { component?: infer Component }
38+
? Component extends FunctionComponent<any>
39+
? ComponentProps<Component>
40+
: never
41+
: never;
42+
43+
// the first one here has a chance to pollute the cache
44+
type Result1 = ComponentProps<typeof ComponentWithForwardRef>;
45+
// that could be incorrectly reused by this one
46+
type Result2 = Test<{ component: typeof ComponentWithForwardRef }>; // no `T` leak
47+
48+
// same as ComponentWithForwardRef above but using a resolved signature instead of a direct inferred result of `forwardRef`
49+
declare const ComponentWithForwardRef2: <T extends FunctionComponent<any>>(
50+
props: PropsWithoutRef<ComponentProps<T>> & {
51+
className?: string;
52+
as?: T | undefined;
53+
} & {
54+
ref?: Ref<HTMLElement> | undefined;
55+
},
56+
) => unknown;
57+
58+
type Result3 = ComponentProps<typeof ComponentWithForwardRef2>;
59+
type Result4 = Test<{ component: typeof ComponentWithForwardRef2 }>;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
declare const EffectTypeId: unique symbol;
5+
6+
interface Variance<out A, out E, out R> {
7+
readonly [EffectTypeId]: VarianceStruct<A, E, R>;
8+
}
9+
10+
type Covariant<A> = (_: never) => A;
11+
12+
interface VarianceStruct<out A, out E, out R> {
13+
readonly _V: string;
14+
readonly _A: Covariant<A>;
15+
readonly _E: Covariant<E>;
16+
readonly _R: Covariant<R>;
17+
}
18+
19+
interface Effect<out A, out E = never, out R = never>
20+
extends Variance<A, E, R> {}
21+
22+
declare const succeed: <A>(value: A) => Effect<A>;
23+
24+
type F<X, Y> = Y extends { _type: infer Z }
25+
? X extends Effect<infer A, infer E, infer R>
26+
? Effect<A, E, R | Z>
27+
: X
28+
: X;
29+
30+
type ProxyMap<Service> = {
31+
[K in keyof Service]: (Service & { _type: Service })[K];
32+
};
33+
34+
declare const implement: <T>() => <I extends ReadonlyArray<any>, X>(
35+
x: (...i: I) => X,
36+
) => (...i: I) => F<X, T>;
37+
38+
class XXX {
39+
log = implement<this>()(<N extends number>(n: N) => succeed(n));
40+
}
41+
42+
export declare const inner: XXX;
43+
export declare const outer: ProxyMap<XXX>;
44+
45+
export const a = inner.log(100); // Effect<100, never, never>
46+
export const b = outer.log(100); // Effect<100, never, XXX>

tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,18 @@ function withP2<P>(p: P) {
1212

1313
const addP2 = withP2({ foo: 1 });
1414
const added2 = addP2({ bar: 2 });
15+
16+
function withP3<P>(p: P) {
17+
const m =
18+
<I,>(from: I) =>
19+
<I2,>(from2: I2) => ({ ...from, ...from2, ...p });
20+
return createTransform(m);
21+
}
22+
23+
const addP3 = withP3({ a: 1 });
24+
const addedSome3 = addP3({ b: '' });
25+
const added3 = addedSome3({ c: true });
26+
27+
const addP3_other = withP3({ foo: 'bar' });
28+
const addedSome3_other = addP3_other({ qwerty: 123 });
29+
const added3_other = addedSome3_other({ bazinga: true });
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// @strict: true
2+
3+
interface Thenable<Value> {
4+
then<V>(
5+
onFulfilled: (value: Value) => V | Thenable<V>,
6+
): Thenable<V>;
7+
}
8+
9+
const toThenable = <Result, Input>(fn: (input: Input) => Result | Thenable<Result>) =>
10+
(input: Input): Thenable<Result> => {
11+
const result = fn(input)
12+
return {
13+
then<V>(onFulfilled: (value: Result) => V | Thenable<V>) {
14+
return toThenable<V, Result>(onFulfilled)(result as Result)
15+
}
16+
};
17+
}
18+
19+
const toThenableInferred = <Result, Input>(fn: (input: Input) => Result | Thenable<Result>) =>
20+
(input: Input): Thenable<Result> => {
21+
const result = fn(input)
22+
return {
23+
then(onFulfilled) {
24+
return toThenableInferred(onFulfilled)(result as Result)
25+
}
26+
};
27+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// https://github.com/microsoft/TypeScript/issues/61633#issuecomment-2841778576
5+
6+
function RenderFlagsMixin<T extends new (...args: any[]) => object>(Base?: T) {}
7+
class Container<T> {
8+
t: T;
9+
}
10+
RenderFlagsMixin(Container);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// @strict: true
2+
3+
declare function wrap<X>(x: X): { x: X };
4+
declare function call<A extends unknown[], T>(x: { x: (...args: A) => T }, ...args: A): T;
5+
6+
const leak = call(wrap(<T>(x: T) => x), 1);

0 commit comments

Comments
 (0)