Closed
Description
Bug Report
π Search Terms
invariant generic, contravariant inference
Maybe related or perhaps because of the same design limitation mentioned in #44999
π Version & Regression Information
Tested with 4.3.5
β― Playground Link
π» Code
declare const d: <T, U>(_: { v: T, m: (t: T) => U, f: (u: U) => void }) => void
declare const a: "a"
declare const b: "b"
d({
v: a,
m: t => t,
f: u => {
let test1: "a" = u // Type 'unknown' is not assignable to type '"a"'.
}
})
d({
v: a,
m: (t: "a") => t,
f: u => {
let test2: "a" = u
}
})
d({
v: a,
m: _ => b,
f: u => {
let test3: "b" = u // Type 'unknown' is not assignable to type '"b"'
}
})
d({
v: a,
m: () => b,
f: u => {
let test4: "b" = u
}
})
π Actual behavior
In 1st and 3rd function call U
gets inferred to unknown
π Expected behavior
In 1st function call U
should get inferred to "a"
and in 3rd function call U
should get inferred to "b"
.
Clearly the contravariant position of U
in m
seems to be a problem because if we annotate it (as done in 2nd call) or omit it (as done in 4th call) it gets inferred to what is expect and there are no error.
A real world use case:
declare const branch:
<T, U extends T>(_: { test: T, if: (t: T) => t is U, then: (u: U) => void }) => void
declare const x: "a" | "b"
branch({
test: x,
if: (t): t is "a" => t === "a",
then: u => {
let test1: "a" = u // Type '"a" | "b"' is not assignable to type '"a"'
}
})
branch({
test: x,
if: (t: "a" | "b"): t is "a" => t === "a",
then: u => {
let test2: "a" = u // compiles
}
})