Home > Software design >  Type 'number' is not assignable to type 'never'
Type 'number' is not assignable to type 'never'

Time:04-20

I am creating custom hook useArray in react with Typescript, I am using Generics for array type as i want any possible value as array element,but then when i try to push any number then it gives me error: Type 'number' is not assignable to type 'never'. and same for any other type as well.if i initialise my array with some values then only that values can be pushed again and not any other values.How to solve this issue?

Here i am providing code : useArray.ts :

import { useState } from "react";
type CompType = string | number;
export default function useArray<T extends CompType>(defaultValue: T[]): {
    array: T[],
    set: React.Dispatch<SetStateAction<T[]>>,
    push: (elemet: T) => void,
    remove: (index: number) => void,
    filter: (callback: (n: T) => boolean) => void,
    update: (index: number, newElement: T) => void,
    clear: () => void

} {
    const [array, setArray] = useState(defaultValue);

    function push(element: T) {
        setArray((a) => [...a, element]);
    }

    function filter(callback: (n: T) => boolean) {
        setArray((a) => a.filter(callback));
    }

    function update(index: number, newElement: T) {
        setArray((a) => [
            ...a.slice(0, index),
            newElement,
            ...a.slice(index   1, a.length),
        ]);
    }

    function remove(index: number) {
        setArray((a) => [...a.slice(0, index), ...a.slice(index   1, a.length)]);
    }

    function clear() {
        setArray([]);
    }

    return { array, set: setArray, push, filter, update, remove, clear };

ArrayComp.tsx :

import useArray from "./useArray";
function ArrayComp() {
  const { array, set, push, remove, filter, update, clear } = useArray([]);

  return (
    <div>
      <h1>Updated array: </h1>
      <div> {array.join(", ")} </div>
      <button onClick={() => set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])}>
        set to[1, 2, 3, 4, 5, 6, 7, 8, 9,10]
      </button>
      <button onClick={() => push(5)}> Add 5 </button>
      <button onClick={() => push("Hello")}> Add "Hello" </button>
      <button onClick={() => update(3, 5)}> update 5 at index 3 </button>
      <button onClick={() => filter((n) => n < 10)}>
        filter numbers less than 10
      </button>
      <button onClick={() => remove(3)}> Remove forth Element </button>
      <button onClick={clear}> Empty array </button>
    </div>
  );
}
export default ArrayComp;

App.tsx :

import "./App.css";
import ArrayComp from "./components/ArrayComp";

function App() {
  return (
    <div className="App">
      <h1>React Custom Hook useArray()</h1>
      <ArrayComp />
    </div>
  );
}

export default App;

CodePudding user response:

When calling useArray() you passed an empty array []. React doesn't really know which type the elements in the array should have based on the empty array, so he assigns T the type unknown.

One possible solution would be to specify the correct type when calling useArray().

const { 
  array, set, push, remove, filter, update, clear 
} = useArray<string | number>([])

Another way to solve this is to make the defaultValue optional.

function useArray<T extends CompType>(defaultValue?: T[]): /* ... */ {
  if (!defaultValue || defaultValue.length === 0) {
      defaultValue = []
  }

  /* ... */
}

If you use useArray() now without any args typescript will assign CompType to T.

const { array, set, push, remove, filter, update, clear } = useArray()
  • Related