-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Contravariance broke in 3.8 when combining spreading parameter list with conditional type #37400
Comments
Tried replacing method-syntax declarations with arrow function equivalents; no effect. @nicojs the simpler the repro the sooner we can look at this; any progress would be appreciated |
Thanks for the encouragement @RyanCavanaugh 💖 I've tried to trim it down further, with moderate success: Maybe some more clues. Performance of compiling a project with typed-inject degraded significantly with 3.8 compared to 3.7 (about 3~4 times slower). See the integration test output snippets below. TypeScript 3.7 (link)
TypeScript 3.8 (link)
|
I think I've trimmed it down to the essentials. interface Injector<TContext> {
injectFunction<Tokens extends (keyof TContext)[]>(todo:
(...args: { [K in keyof Tokens]: Tokens[K] extends keyof TContext ? TContext[Tokens[K]] : never; }) => void): void;
}
declare const rootInjector: Injector<{}>;
const fooInjector: Injector<{ foo: string}> = rootInjector; // Missing error here in TS 3.8 The error seems to occur when combining a conditional type with spreading parameter lists with tuples. I'll also update the title and the initial message to better reflect this. |
@weswigham or @RyanCavanaugh any updates on this? Would this make it into TypeScript 4.0? 😇 |
So I took a peek at this one today, and despite the small repro, there are a few issues going on at once. First: When comparing instantiations of the same signature (as we do here for the declare const phantomData: unique symbol;
interface Injector<TContext> {
[phantomData]?: TContext;
injectFunction<Tokens extends (keyof TContext)[]>(todo:
(...args: { [K in keyof Tokens]: Tokens[K] extends keyof TContext ? TContext[Tokens[K]] : never; }) => void): void;
}
declare const rootInjector: Injector<{}>;
const fooInjector: Injector<{ foo: string}> = rootInjector; Using Second: Once there's a fix or workaround for that in place, this So this small example seems to hit upon a lot of our relationship checking flaws all at once~ |
Thanks for looking into this @weswigham I'm not following all the details here, but am I correct in assuming that once #30639 and #31029 are merged this issue is fixed? 👐 |
Based on my understanding on the workings of the problem, yes. |
@weswigham #31029 is closed! 😨 Is there a follow-up planned? I guess this isn't a "Good first issue" thing? |
I... Dunno. I wasn't even responsible for getting #30639 merged - I'm actually mostly just idly browsing notifications while I'm conscious while in the hospital (heh). @sandersn might know if there's a larger area he's trying to merge fixes in and would better know if #31029 and updating it meets that bar for him. |
I closed #31029 because it had been sitting stale for a year after we decided in the design meeting that it needed some more design work. It's still worthwhile to follow up on the design meeting recommendations and see if they work out. |
Wow! Is it Christmas already? This bug seems to be fixed in TS 4.5. @weswigham can you confirm? 🎄 |
This does seem fixed 👍 |
TypeScript Version: 3.8.3
Search Terms: variance contravariance
Description: An Injector in typed-inject is a dependency injection container that is type safe. It can only provide values for tokens it knows. A small example:
It makes sense that an injector
Injector<{}>
is not assignable toInjector<{foo: string}>
, since it cannot provide a value for token'foo'
. This was the case in TS 3.7. However, since TS 3.8,Injector<{}>
is assignable toInjector<{foo: string}>
😪.Expected behavior:
Type 'Injector<{}>' is not assignable to type 'Injector<{ foo: string; }>'.
Actual behavior: No error
Related Issues: Couldn't find any 🤷♂️
Code
I think I've trimmed it down to the essentials.
Output
(none)
Compiler Options
Playground Link: Provided
Simpler contravariant examples like this still work as expected.
The text was updated successfully, but these errors were encountered: