What is "not assignable to parameter of type never" error in TypeScript?

Typescript

Typescript Problem Overview


Code is:

const foo = (foo: string) => {
  const result = []
  result.push(foo)
}

I get the following TS error:

> [ts] Argument of type 'string' is not assignable to parameter of type 'never'.

What am I doing wrong? Is this a bug?

Typescript Solutions


Solution 1 - Typescript

All you have to do is define your result as a string array, like the following:

const result : string[] = [];

Without defining the array type, it by default will be never. So when you tried to add a string to it, it was a type mismatch, and so it threw the error you saw.

Solution 2 - Typescript

Another way is:

const result: any[] = [];

Solution 3 - Typescript

This seems to be some strange behavior in typescript that they are stuck with for legacy reasons. If you have the code:

const result = []

Usually it would be treated as if you wrote:

const result:any[] = []

however, if you have both noImplicitAny FALSE, AND strictNullChecks TRUE in your tsconfig, it is treated as:

const result:never[] = []

This behavior defies all logic, IMHO. Turning on null checks changes the entry types of an array?? And then turning on noImplicitAny actually restores the use of any without any warnings??

When you truly have an array of any, you shouldn't need to indicate it with extra code.

Solution 4 - Typescript

I got the same error in ReactJS function component, using ReactJS useState hook.

The solution was to declare the type of useState at initialisation using angle brackets:

// Example: type of useState is an array of string
const [items , setItems] = useState<string[]>([]); 

Solution 5 - Typescript

I was having same error In ReactJS statless function while using ReactJs Hook useState. I wanted to set state of an object array , so if I use the following way

const [items , setItems] = useState([]);

and update the state like this:

 const item = { id : new Date().getTime() , text : 'New Text' };
 setItems([ item , ...items ]);

I was getting error:

Argument of type '{ id: number; text: any }' is not assignable to parameter of type 'never'

but if do it like this,

const [items , setItems] = useState([{}]);

Error is gone but there is an item at 0 index which don't have any data(don't want that).

so the solution I found is:

const [items , setItems] = useState([] as any);

Solution 6 - Typescript

The solution i found was

const [files, setFiles] = useState([] as any);

Solution 7 - Typescript

Assuming your linter is okay with "any" types:

If you don't know the type of values that will fill the Array, you can do this and result will infer the type.

const result: any[] = []

04/26/2022: Coming back to this I think the solution you may have been looking for may be something like this:

const foo = (foo: string) => {
  const result: string[] = []
  result.push(foo)
}

You needed specify what the array is since result = [] has a return type of any[]. Typically you want to avoid any types since they are meant to be used as an "Escape hatch" according to Microsoft.

The result is an object that is an array that expects type string values or something that includes a string such as string | number.

Solution 8 - Typescript

I was able to get past this by using the Array keyword instead of empty brackets:

const enhancers: Array<any> = [];

Use:

if (typeof devToolsExtension === 'function') {
  enhancers.push(devToolsExtension())
}

Solution 9 - Typescript

Error: Argument of type 'any' is not assignable to parameter of type 'never'.

In tsconfig.json -

  "noImplicitReturns": false,

   "strictNullChecks":false,

enter image description here

Solution: type as 'never'

enter image description here

Solution 10 - Typescript

You need to type result to an array of string const result: string[] = [];.

Solution 11 - Typescript

Remove "strictNullChecks": true from "compilerOptions" or set it to false in the tsconfig.json file of your Ng app. These errors will go away like anything and your app would compile successfully.

Disclaimer: This is just a workaround. This error appears only when the null checks are not handled properly which in any case is not a good way to get things done.

Solution 12 - Typescript

One more reason for the error.

if you are exporting after wrapping component with connect()() then props may give typescript error
Solution: I didn't explore much as I had the option of replacing connect function with useSelector hook
for example

/* Comp.tsx */
interface IComp {
 a: number
}

const Comp = ({a}:IComp) => <div>{a}</div>

/* ** 

below line is culprit, you are exporting default the return 
value of Connect and there is no types added to that return
value of that connect()(Comp) 

** */

export default connect()(Comp)


--
/* App.tsx */
const App = () => {
/**  below line gives same error 
[ts] Argument of type 'number' is not assignable to 
parameter of type 'never' */
 return <Comp a={3} />
}

Solution 13 - Typescript

I got the error when defining (initialising) an array as follows:

let mainMenu: menuObjectInterface[] | [] = [];

The code I got the problem in:

let mainMenu: menuObjectInterface[] | [] = [];
dbresult.rows.forEach((m) => {
    if (!mainMenu.find((e) => e.menucode === m.menucode)) {
        // Not found in mainMenu, yet
        mainMenu.push({menucode: m.menucode, menudescription: m.menudescription})  // Here the error
    }
})

The error was: TS2322: Type 'any' is not assignable to type 'never'

The reason was that the array was initialised with also the option of an empty array. Typescript saw a push to a type which also can be empty. Hence the error.

Changing the line to this fixed the error:

let mainMenu: menuObjectInterface[] = [];

Solution 14 - Typescript

you could also add as string[]

const foo = (foo: string) => {
  const result = []
  (result as string[]).push(foo)
}

I did it when it was part of an object

let complexObj = {
arrData : [],
anotherKey: anotherValue
...
}
(arrData as string[]).push('text')

Solution 15 - Typescript

All you have to do is define your result as a any array, like the following:

result : any = [];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLevView Question on Stackoverflow
Solution 1 - TypescriptTha'er M. Al-AjlouniView Answer on Stackoverflow
Solution 2 - TypescriptneomibView Answer on Stackoverflow
Solution 3 - TypescriptRandy HudsonView Answer on Stackoverflow
Solution 4 - TypescriptneiyaView Answer on Stackoverflow
Solution 5 - TypescriptImFarhadView Answer on Stackoverflow
Solution 6 - TypescriptLakshan HettiarachchiView Answer on Stackoverflow
Solution 7 - TypescriptShahView Answer on Stackoverflow
Solution 8 - TypescriptMickersView Answer on Stackoverflow
Solution 9 - Typescriptrohit.khurmi095View Answer on Stackoverflow
Solution 10 - TypescriptdomreadyView Answer on Stackoverflow
Solution 11 - TypescriptAshutosh SinghView Answer on Stackoverflow
Solution 12 - TypescriptAkshay Vijay JainView Answer on Stackoverflow
Solution 13 - TypescriptBertCView Answer on Stackoverflow
Solution 14 - TypescriptHadar ShpivakView Answer on Stackoverflow
Solution 15 - Typescriptmiral View Answer on Stackoverflow