-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generic inference inside of pipe
is incorrect when strict mode is disabled
#25826
Comments
from #25637 : class C1 { P1: string; }
class C2 { P2: string; }
class C3 { P3: string; }
function a(value: C1 | null): string;
function a(value: C2 | null): string;
function a(value: C1 | C2 | null): string {
return "";
}
var c = (value?: C1 | C2 | C3 | null | undefined): string => {
if (value instanceof C1 || value instanceof C2)
return a(value); // C1 | C2 --> not null or undefined, there is no reasons to give an error...
// is a(C1) a valid call? YES
// is a(C2) a valid call? YES
// why error?
return value ? value.P3 : "";
}
var b = (value?: C1 | C2 | C3 | null | undefined): string => {
if (value instanceof C1) return a(value); // C1
if (value instanceof C2) return a(value); // C2
return value ? value.P3 : "";
} |
@dardino This issue is concerning overloads when used with a pipe function, which doesn't appear to be the case with your issue. Perhaps you could open a new issue to avoid conflating the issue being tracked here? |
Ok sorry |
@mhegazy How come this is marked as a suggestion? Isn't this a bug? |
@OliverJAsh It's an effect (or limitation) of our type inference algorithm. In the call to We might explore doing better in situations where instantiation of a generic function argument in the context of a function type parameter causes fixing of type parameters and attempt to delay inference from such arguments further. That would be what the "Suggestion" label refers to. |
After a fairly long discussion of options here, we don't have any ideas for how to fix this without breaking other scenarios. Full unification is of course a "solution" but that's basically a complete ground-up rewrite, so not really in the cards for the time being. |
Simpler test case for this: declare const pipe: {
// Workaround 1: enable this overload
// <A, B, C>(ab: (a: A) => B, bc: (b: B) => C): (a: A) => C;
<A, B, C, D>(ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): (a: A) => D;
};
declare const getString: () => string;
declare const orUndefined: (name: string) => string | undefined;
declare const identity: <T>(value: T) => T;
const fn = pipe(
getString,
/*
Unexpected type error:
Type 'string | undefined' is not assignable to type '{}'.
Type 'undefined' is not assignable to type '{}'.
*/
string => orUndefined(string),
// Workaround 2: pass the function directly, instead of wrapping:
// get,
identity,
); As mentioned in #29904. |
TypeScript Version: 2.9.2
Search Terms:
Code
With strict mode disabled:
Related Issues:
This is similar to—but not exactly the same as—other issues I've filed when trying to use
pipe
:pipe
#25637pipe
#25791The text was updated successfully, but these errors were encountered: