While working on a library, I discovered what to me looks like a bug when using Generics:
type R<A> = A extends Bottom ? A : A
type Bottom = { test: number }
const f = <A extends Bottom>(a: A) => {
useIt(a) // type error here
}
const useIt = <A extends Bottom>(a: R<A>) => console.log(a)
As you can also see in the
Playground example, for some unclear reason a cannot be used as R<A>, even though this type is equivalent to A.
The type error is:
Argument of type 'A' is not assignable to parameter of type 'R<A>'.
Type 'Bottom' is not assignable to type 'R<A>'.
Using a concrete type instead of a generic will work as expected, eg:
type X = {test: 1}
const x: R<X> = {test: 1} // all good
const noX: R<X> = {test: 2} // error
Having a better restriction type will also work as expected for concrete types:
type R<A> = A extends Bottom ? A : never
const x: R<X> = {test: 1} // all good
const error: R<{}> = {} // type error as expected given that {} doesn't extend Bottom
So, is there any way to make it work with Generics?