🔎 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
https://www.typescriptlang.org/play/?ts=6.0.3#code/C4TwDgpgBAwg9gNwDwBUB8UC8UDeUBOEAhgCZwB2ANiFAB4BcUKUAvgNwBQokUAIgJYBnYPnjJ0WJlAi1gEciUFSA-LESoMjchAQR8nDgDMAruQDGwfhShzhYjQAoijAcNHr0AGigAjRvfQASlwOKCgAenCoAHkAaX91AEEMISgiQUF+AHNyIh9KaGA4NWREqAAfKAAhNFC0qEEiS0FDfgglALQDMMioAAFgQQBaGUgLEfx8OHwSpDLKmqhU8jhgNIzs3PzC4vtkup8GpqFW9r4hEU7OFg4ucGh4chEiDUkHBiZgzAwEOH4STjcaCuS4UZ6vbDMGRyBRKZiqR7giRaHR6AwmcyWay2YCI-AvdBOFwXdxPfEabx+NRkgloYI4Oq9AbDUYQcZ6KYzPEvZINAAWcGMlBIUBWax80HSmRyeQKNl2YPJ82qtTCRCOzVOHUVtO6ESi3LmFRV-MFwt8ko2Mu28up4P2YUOjU1bSUINJSK6HBYQA
💻 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 as Contra<T>, although it should not be.
Contra<T> is rejected as DistrContra<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
🔎 Search Terms
"conditional type distribution contravariance" "distributive conditional assignability" "variance conditional types"
🕗 Version & Regression Information
⏯ Playground Link
https://www.typescriptlang.org/play/?ts=6.0.3#code/C4TwDgpgBAwg9gNwDwBUB8UC8UDeUBOEAhgCZwB2ANiFAB4BcUKUAvgNwBQokUAIgJYBnYPnjJ0WJlAi1gEciUFSA-LESoMjchAQR8nDgDMAruQDGwfhShzhYjQAoijAcNHr0AGigAjRvfQASlwOKCgAenCoAHkAaX91AEEMISgiQUF+AHNyIh9KaGA4NWREqAAfKAAhNFC0qEEiS0FDfgglALQDMMioAAFgQQBaGUgLEfx8OHwSpDLKmqhU8jhgNIzs3PzC4vtkup8GpqFW9r4hEU7OFg4ucGh4chEiDUkHBiZgzAwEOH4STjcaCuS4UZ6vbDMGRyBRKZiqR7giRaHR6AwmcyWay2YCI-AvdBOFwXdxPfEabx+NRkgloYI4Oq9AbDUYQcZ6KYzPEvZINAAWcGMlBIUBWax80HSmRyeQKNl2YPJ82qtTCRCOzVOHUVtO6ESi3LmFRV-MFwt8ko2Mu28up4P2YUOjU1bSUINJSK6HBYQA
💻 Code
🙁 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