Effect CommunityEC
Effect Community15mo ago
12 replies
qlonik

TypeScript Variance Issue with `never` Type in Function Signature

Hey, sorry if its a stupid question, but I think I'm confused with either variance in TS or assignability of never type. How come in the following snippet, the first call to fn with error type specified as never does not work, but second call to fn with error type instantiated as Error passes?

interface Left<E> {
  readonly _tag: 'left'
  readonly value: E
}
interface Right<A> {
  readonly _tag: 'right'
  readonly value: A
}
type Either<A, E> = Right<A> | Left<E>

declare function right<A, E = never>(value: A): Either<A, E>

class Something<A, E> {
  readonly _tag = 'Something'

  constructor(
    readonly task: () => Either<A, E>,
    readonly onFinish: (e: Either<A, E>) => void,
  ) {}
}

declare function fn<T extends Something<any, any>>(x: T): T

fn(
  new Something(
    (): Either<number, never> => right(123),
    (_) => {},
  ),
)

fn(
  new Something(
    (): Either<number, Error> => right(123),
    (_) => {},
  ),
)


error:
TS2345: Argument of type 'Something<number, never>' is not assignable to parameter of type 'Something<any, any>'.
  Types of property 'onFinish' are incompatible.
    Type '(e: Either<number, never>) => void' is not assignable to type '(e: Either<any, any>) => void'.
      Types of parameters 'e' and 'e' are incompatible.
        Type 'Either<any, any>' is not assignable to type 'Either<number, never>'.
          Type 'Left<any>' is not assignable to type 'Either<number, never>'.
            Type 'Left<any>' is not assignable to type 'Left<never>'.
              Type 'any' is not assignable to type 'never'.

25   new Something(
     ~~~~~~~~~~~~~~
26     (): Either<number, never> => right(123),
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27     (_) => {},
   ~~~~~~~~~~~~~~
28   ),
   ~~~
Was this page helpful?