-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Closed
Description
🔎 Search Terms
variance annotations, type aliases, interfaces, assignability
🕗 Version & Regression Information
Previously noticed here for #56390 #56418, it still seems very strange. Is this behavior really intended?
This behavior exists since #56418 and looks like a bug.
⏯ Playground Link
💻 Code
interface FooInterface<out T> {
_: () => T
}
type FooType<out T> = {
_: () => T
}
namespace InterfaceBehavior {
namespace WithInterface {
interface InvariantFoo<in out T> extends FooInterface<T> {}
declare let arr: InvariantFoo<1 | 2>
declare let brr: InvariantFoo<1>
arr = brr // Invariance holds -> arr and brr are not assignable to each other
brr = arr
type t1 = [ // Both are false
// ^?
typeof arr extends typeof brr ? true : false,
typeof brr extends typeof arr ? true : false
]
}
namespace WithTypeAlias {
interface InvariantFoo<in out T> extends FooType<T> {}
declare let arr: InvariantFoo<1 | 2>
declare let brr: InvariantFoo<1>
arr = brr // Invariance holds -> arr and brr are not assignable to each other
brr = arr
type t1 = [ // Both are false
// ^?
typeof arr extends typeof brr ? true : false,
typeof brr extends typeof arr ? true : false
]
}
}
namespace TypeAliasBehavior {
namespace WithInterface {
type InvariantFoo<in out T> = FooInterface<T>
declare let arr: InvariantFoo<1 | 2>
declare let brr: InvariantFoo<1>
arr = brr // For some reason these are still covariant?
brr = arr
type t1 = [ // [false, true]
// ^?
typeof arr extends typeof brr ? true : false,
typeof brr extends typeof arr ? true : false
]
}
namespace WithTypeAlias {
type InvariantFoo<in out T> = FooType<T>
declare let arr: InvariantFoo<1 | 2>
declare let brr: InvariantFoo<1>
arr = brr // Invariance holds -> arr and brr are not assignable to each other
brr = arr
type t1 = [ // Both are false
// ^?
typeof arr extends typeof brr ? true : false,
typeof brr extends typeof arr ? true : false
]
}
}🙁 Actual behavior
Restricting variance with annotations works in all cases EXCEPT for a type alias for an interface.
🙂 Expected behavior
I don't expect any difference between these cases. This is extremely unintuitive if intended.
Additional information about the issue
No response
Metadata
Metadata
Assignees
Labels
No labels