🔎 Search Terms
contravariance strictFunctionTypes function method
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about strictFunctionTypes and the distinction between function and method properties during typechecking.
⏯ Playground Link
https://www.typescriptlang.org/play/?ts=6.0.0-dev.20260416#code/C4TwDgpgBAogHgQwLZgDYQDwBUoF4oDOwATgJYB2A5lAD5TkCuSARhMQHx5QDeAsAFBQoAemFQAshGAALAPYATQiHLAEcAUKRS58gBRwAXFCwBKIwDdZpeQG4NIsQDEG5AMbBSs8kpVr7AMxdXI30jUzxOS2s7fgBfGIFAtw8vKH8AJlDYRBR0DCIyKnYTHns4ADotGQUuLIKKShLcTlcvAll0ctRZSn0TGKEKpNdaw0ISBqaWto6ILp6+mNiBAVEoAHViL0pUECgEV1cIMGACA1WxAAMhoMuoVwRvL12oYggj0nNoeqoCABooMwGMAoDJoGAEAQCBBFAhiJQmBAVKDZGl0vtUN0AO4EC70JisYgEFGA6AMaGKLHSJH3BCYhpQCA5NAQdLlYa6MwCVrkIiM5nodH4bixfbE+DIFn5CZUWj4lhsdgxDK6JmSwX9ARq3Ks9lBXQARgADJr+HisKj-KQ4KDpKQzvt5Ip5EwkHstAqiaDwDCxbboMMUt4IcRkFI2N7IGcLnjQJBsurMDh8D9qHRGJ7OMK8UIoAB9PNwyhYH1hGJrXPlKt42JAA
💻 Code
type Example<T = string | number> = {
// Function syntax
func: (x: T) => void;
};
function f2(x: Example<string>) {
x.func = (x: string) => console.log(x);
}
// Wrongly accepts:
// `x.func` can only receive strings, but the passed argument to f2 allows
// numbers to be used when calling example2.func():
const example2 = {} as Example<string | number>;
f2(example2);
example2.func(10); // will pass a number instead of a string which is now expected by the callback assigned by f2
🙁 Actual behavior
The call f2(example2) does not produce any errors. See below to why I believe this is wrong.
🙂 Expected behavior
The call f2(example2) should error on the fact that Example<string | number> cannot fit Example<string> because func -- which here is typed as a function property, not a method property -- is contravariant on its argument.
I emphasize that this already takes into consideration the usual distinction between "method syntax" vs. "function syntax" as specified in the FAQ and several other related bug reports, such as #53798.
This comment: #53798 (comment) suggest strictFunctionTypes would apply to the situation here described, so I wonder if this is a bug or actually a design limitation of some sort.
Additional information about the issue
Adding a dummy member such as:
type Example<T = string | number> = {
__argType: T;
/*...*/
}
is an (ugly) workaround that mostly makes the type checker work as intended.
🔎 Search Terms
contravariance strictFunctionTypes function method
🕗 Version & Regression Information
⏯ Playground Link
https://www.typescriptlang.org/play/?ts=6.0.0-dev.20260416#code/C4TwDgpgBAogHgQwLZgDYQDwBUoF4oDOwATgJYB2A5lAD5TkCuSARhMQHx5QDeAsAFBQoAemFQAshGAALAPYATQiHLAEcAUKRS58gBRwAXFCwBKIwDdZpeQG4NIsQDEG5AMbBSs8kpVr7AMxdXI30jUzxOS2s7fgBfGIFAtw8vKH8AJlDYRBR0DCIyKnYTHns4ADotGQUuLIKKShLcTlcvAll0ctRZSn0TGKEKpNdaw0ISBqaWto6ILp6+mNiBAVEoAHViL0pUECgEV1cIMGACA1WxAAMhoMuoVwRvL12oYggj0nNoeqoCABooMwGMAoDJoGAEAQCBBFAhiJQmBAVKDZGl0vtUN0AO4EC70JisYgEFGA6AMaGKLHSJH3BCYhpQCA5NAQdLlYa6MwCVrkIiM5nodH4bixfbE+DIFn5CZUWj4lhsdgxDK6JmSwX9ARq3Ks9lBXQARgADJr+HisKj-KQ4KDpKQzvt5Ip5EwkHstAqiaDwDCxbboMMUt4IcRkFI2N7IGcLnjQJBsurMDh8D9qHRGJ7OMK8UIoAB9PNwyhYH1hGJrXPlKt42JAA
💻 Code
🙁 Actual behavior
The call
f2(example2)does not produce any errors. See below to why I believe this is wrong.🙂 Expected behavior
The call
f2(example2)should error on the fact thatExample<string | number>cannot fitExample<string>becausefunc-- which here is typed as a function property, not a method property -- is contravariant on its argument.I emphasize that this already takes into consideration the usual distinction between "method syntax" vs. "function syntax" as specified in the FAQ and several other related bug reports, such as #53798.
This comment: #53798 (comment) suggest
strictFunctionTypeswould apply to the situation here described, so I wonder if this is a bug or actually a design limitation of some sort.Additional information about the issue
Adding a dummy member such as:
is an (ugly) workaround that mostly makes the type checker work as intended.