Skip to content
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

Strange behaviour with assignability and generics #36311

Open
ElusiveMori opened this issue Jan 19, 2020 · 1 comment
Open

Strange behaviour with assignability and generics #36311

ElusiveMori opened this issue Jan 19, 2020 · 1 comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Milestone

Comments

@ElusiveMori
Copy link

ElusiveMori commented Jan 19, 2020

TypeScript Version: 3.7.2

Search Terms:

I've read through the related issues and the origin behind this error message, but I still can't wrap my head around this particular case, and it feels like a bug to me. In particular, this feels extra weird because the issue goes away if I just add an extra generic parameter on the interface - even though they are really doing the same thing.

It feels like TypeScript should be able to figure out, that if I pass e.g. Hello1<(a: number) => void> to whoops(), then it should be able to resolve C into (a: number) => void and A into [number]. And if, for some reason, the callee specifies an incompatible set of generics to the functions, that is should fail then, instead of at the function definition.

There are some variations I've tried on the exact signature of the function, but I haven't found anything that works.

Expected behavior: Both examples compile.

Actual behavior: Only one example compiles. The other fails with:

Type 'C' does not satisfy the constraint '(...args: any[]) => void'.
  Type '(...args: A) => void' is not assignable to type '(...args: any[]) => void'.
    Types of parameters 'args' and 'args' are incompatible.
      Type 'any[]' is not assignable to type 'A'.
        'any[]' is assignable to the constraint of type 'A', but 'A' could be instantiated with a different subtype of constraint 'any[]'.

Related Issues: #29049

Code

// this doesn't work
interface Hello1<C extends (...args: any[]) => void> {
    _1: C
}

function whoops<A extends any[], C extends (...args: A) => void>(
    hello: Hello1<C>
) {}

// this does!
interface Hello2<A extends any[], C extends (...args: A) => void> {
    _1: A
    _2: C
}

function ok<A extends any[], C extends (...args: A) => void>(
    bye: Hello2<A, C>
) { }
Compiler Options
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "useDefineForClassFields": false,
    "alwaysStrict": true,
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "downlevelIteration": false,
    "noEmitHelpers": false,
    "noLib": false,
    "noStrictGenericChecks": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "esModuleInterop": true,
    "preserveConstEnums": false,
    "removeComments": false,
    "skipLibCheck": false,
    "checkJs": false,
    "allowJs": false,
    "declaration": true,
    "experimentalDecorators": false,
    "emitDecoratorMetadata": false,
    "target": "ES2017",
    "module": "ESNext"
  }
}

Playground Link: Provided

@midevelop
Copy link

Yes.
It's very strange!

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Jan 23, 2020
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Jan 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

No branches or pull requests

3 participants