Open OliverJAsh opened 4 years ago
What's the definition of memo
?
If someone can provide an isolated repro we can investigate
@RyanCavanaugh Hope this helps:
// The presence of any overloads confuses inference, leave just one of them in and everything works
declare function memo<T>(Component: T): T;
declare function memo<T>(Component: T): T;
declare function pipeWith<A, B>(a: A, ab: (a: A) => B): B;
type Props = { foo: number };
declare const MyComponent: Props;
// β
correct props type
// Props
const r1 = memo(MyComponent);
// β `unknown` props type
// unknown
const r2 = pipeWith(MyComponent, memo);
// Workaround
// β
correct props type
// Props
const r3 = pipeWith(MyComponent, (C) => memo(C));
Just the presence of any overloads will confuse the inference on the original use case. Leave just the one signature and everything works as expected.
I'm running into this all of the time, not just when using React.memo
.
Example using Object.values
:
declare function pipe<A, B>(a: A, ab: (a: A) => B): B;
// Type of `value1` is `any[]`, expected `(string | number)[]`
const value1 = pipe({ foo: 1, bar: 'abc' }, Object.values);
// Workaround:
const value2 = pipe({ foo: 1, bar: 'abc' }, (x) => Object.values(x));
Here's another example when using RxJS v7 (7.0.0
). I've reduced the test case down further in this playground.
import { lastValueFrom, of } from 'rxjs';
import { tap } from 'rxjs/operators';
declare function pipe<A, B>(a: A, ab: (a: A) => B): B;
//
// `of` example
//
{
// Type of `value1` is `Observable<never>`, expected `Observable<string>`
const value1 = pipe('foo', of);
// Workaround:
const value2 = pipe('foo', (x) => of(x));
}
//
// `lastValueFrom` example
//
pipe(of('foo'), lastValueFrom).then((x) => {
// Type of `x` is `unknown`, expected `string`
x;
});
// Workaround:
pipe(of('foo'), (ob) => lastValueFrom(ob)).then((x) => {
x;
});
//
// `tap` example
//
declare const hof: <T>(g: (t: T) => void) => (t: T) => void;
of('foo').pipe(
tap(
hof((x) => {
// Type of `x` is `unknown`, expected `string`
x;
}),
),
);
// Workaround:
of('foo').pipe(
tap((value) =>
pipe(
value,
hof((x) => {
x;
}),
),
),
);
TypeScript Version: 3.9.2
Search Terms: generic pipe pipeWith react memo HOC props any
Code
Using latest version of
@types/react
(at the time of writing: 16.9.35).Expected behavior:
See above.
Actual behavior:
See above.
Playground Link:
https://stackblitz.com/edit/react-ts-4ih6jn
Related Issues:
https://github.com/microsoft/TypeScript/issues/25637, although that was closed as a duplicate of an issue which has since been closed (https://github.com/microsoft/TypeScript/issues/10957), so I decided to post a new issue.