microsoft / microsoft/TypeScript
Assignability between distributive conditional types and their branch type is reversed in contravariant positions
Abierto
@ahejlsberg ya está trabajando en esto.
Desde el 30/7/2026.
Needs Investigation
- Lenguaje dominante
- Go
- Estrellas
- 111k
- Forks
- 14.3k
- Merge medio
- 2 d 4 h
- PR fusionados (30 d)
- 132
Descripción
🔎 Search Terms
"conditional type distribution contravariance" "distributive conditional assignability" "variance conditional types"
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about conditional types, distributive conditional types, and variance
⏯ Playground Link
💻 Code
type Cov<T> = { readonly x: T };
type DistrCov<T> = T extends T ? Cov<T> : never;
function testCov<T>(a: DistrCov<T>, b: Cov<T>) {
// OK: Cov<A> is assignable to Cov<A | B>
a satisfies Cov<T>;
// @ts-expect-error Cov<A | B> is not assignable to Cov<A>
b satisfies DistrCov<T>;
}
type Contra<T> = (x: T) => void;
type DistrContra<T> = T extends T ? Contra<T> : never;
function testContra<T>(a: DistrContra<T>, b: Contra<T>) {
// @ts-expect-error Contra<A> should not be assignable to Contra<A | B>
a satisfies Contra<T>;
// Contra<A | B> should be assignable to Contra<A>
b satisfies DistrContra<T>;
}
🙁 Actual behavior
The covariant case behaves as expected.
The contravariant case appears inverted:
DistrContra<T>is accepted asContra<T>, although it should not be.Contra<T>is rejected asDistrContra<T>, although it should be.
🙂 Expected behavior
The contravariant case should mirror the covariant one with assignability reversed.
Since conditional distribution over a union produces Contra<A> | Contra<B> | ..., it should only be assignable in the contravariant direction.
Additional information about the issue
No response
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Evaluación
Este issue todavía no se ha evaluado.