TypeScript: Regression causes Function top-type to be callable with no arguments
Bug Report
đ Search Terms
function top type callable spread never regression
đ Version & Regression Information
- This changed between versions 3.8.3 and 3.9.7
⯠Playground Link
Playground link with relevant code
đ» Code
declare let foo: (...args: never) => void;
foo = (x: string) => {};
foo(); // no error
đ Actual behavior
foo() was permitted.
đ Expected behavior
foo() should not be permitted because it is unsafe. (...args: never) => unknown behaves as the top-type for all functions; all function types are assignable to it. So calling it will lead to unsafe behavior by functions expecting 1 or more arguments.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 3
- Comments: 18 (15 by maintainers)
So, just running into this again, presumably
declare const f: (...args: never[]) => unknownshould allowf()because[]is assignable tonever[], butdeclare const g: (...args: never) => unknownshould not allowg()because[]is not assignable tonever. And therefore(...args: never) => unknownis a top type for functions but(...args: never[]) => unknownshouldnât be.Right now both types are callable with no arguments and both of these are considered top types for functions. Which of these can we fix without breaking everyone?
Are you saying that the type
(...args: never) => voiddoesnât make sense and should be removed? It seems perfectly logical as a top function type; the type of...argsis, in a sense, the intersection of all possible argument types, which isnever. You canât call a function of type(...args: never) => void, because you donât know what arguments it takes, but you know that it is something that could be theoretically called, you just donât know what it could be called with. Itâs like{}being the top type of property-bearing things; you canât directly access properties on it, because you donât know what properties it might have, but you know that it has properties that could theoretically be accessed.Ah, good point.
Would it break the universe if we stopped
(...args: never[]) => unknownfrom being considered a top type? No function that requires an argument should be assignable to it. (e.g.,const f: (...args: never[])=>unknown = (x: string) => x.toUpperCase(); f();compiles and explodes at runtime.) Iâm guessing itâs been used as a top type in various real-worldy places and these would be broken if the change were made. But Iâd at least like to see an official âwe know this is unsound but itâs too late to touch it nowâ comment somewhere I can refer people to.Upon further reflection, I think youâre right about
(args: never)So can we confirm that this is a bug and not just âneeds investigationâ anymore, given the discussion in #35438 ?
But
[string]isnât assignable tonever[]. Seems that that there is another case of unsoundness with(...args: never[]) => unknown.I think it is just broken that
(...args: never) => unknownis callable.