0

This situation is as follows:

interface Handler1<S>{
  handle(s: S): any
}

interface Handler2<S> {
  handler: (s: S) => any
}

declare function higherOrder1(handler: Handler1<unknown>): unknown
declare function higherOrder2(handler: Handler2<unknown>): unknown

declare const h1: Handler1<number>
declare const h2: Handler2<number>

higherOrder1(h1) // Typechecks, bug???
higherOrder2(h2) // Does not typecheck, as expected

It seems to me that neither higherOrder1(h1) nor higherOrder2(h2) should type check, as unknown is not assignable to number. Is there a reason why higherOrder1(h1) type checks?

This seems to be an issue specifically with the handle(s: S): T notation. Working directly with functions behaves as expected.

declare function higherOrder3(fn: (u: unknown) => number): unknown
const fn1 = (x: number) => x
function fn2(x: number){
  return x
}

// Neither of these three type check, as expected.
higherOrder3(fn1)
higherOrder3(fn2)
  • What do you mean by "typecheck"? It throws an error? – kelsny Feb 07 '23 at 19:56
  • methods are bivariant, however, function properties in an interface are contravariant in TS – VLAZ Feb 07 '23 at 20:01
  • Yep that's it VLAZ. [This post](https://stackoverflow.com/questions/74934661/what-causes-this-discrepancy-in-type-checking-behavior-based-on-interface-declar) brought me to [strict-function-types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-6.html#strict-function-types). – Aaron Greenspan Feb 07 '23 at 20:14
  • @vera. I mean the opposite, I think (thought) it ought to throw an error as I expected contravariant function type checking for methods, but apparently strict-function-types still checks methods covariantly. – Aaron Greenspan Feb 07 '23 at 20:15

0 Answers0