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:
declareconstfooInjector: Injector<{foo: string}>;// this injector can provide string values for the token 'foo'constfoo=fooInjector.resolve('foo');// => typeof foo === 'string'fooInjector.resolve('bar');// => Error ts(2345) Argument of type '"bar"' is not assignable to parameter of type '"foo"'It makes sense that an injector Injector<{}> is not assignable to Injector<{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 to Injector<{foo: string}> 😪.
declareconstrootInjector: Injector<{}>;constfooInjector: Injector<{foo: string}>=rootInjector;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.
interfaceInjector<TContext>{injectFunction<Tokensextends(keyofTContext)[]>(todo:
(...args: {[KinkeyofTokens]: Tokens[K]extendskeyofTContext ? TContext[Tokens[K]] : never;})=>void): void;}declareconstrootInjector: Injector<{}>;constfooInjector: Injector<{foo: string}>=rootInjector;Output
(none)
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": 2,
"target": "ES2017",
"jsx": "React",
"module": "ESNext"
}
}Playground Link:Provided
Simpler contravariant examples like this still work as expected.
typeAction<T>=(arg: T)=>void;declareletb: Action<{}>;declareleta: Action<{foo: number}>;b=a// => Error! Type 'Action<{ foo: number; }>' is not assignable to type 'Action<{}>'.
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
{ "compilerOptions": { "noImplicitAny": true, "strictNullChecks": true, "strictFunctionTypes": true, "strictPropertyInitialization": true, "strictBindCallApply": true, "noImplicitThis": true, "noImplicitReturns": true, "alwaysStrict": true, "esModuleInterop": true, "declaration": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "moduleResolution": 2, "target": "ES2017", "jsx": "React", "module": "ESNext" } }Playground Link:Provided
Simpler contravariant examples like this still work as expected.