skip to Main Content

Description: I’m trying to update my useState, newCase, with property values coming from a form.

Problem: Assigning the value results in the error: Type ‘string’ is not assignable to type ‘never’, and I don’t know how to fix it.

Here’s the interface of a case object:

  export interface ICases {
  materials: Material[]
  finalActivity: boolean
  existingCase: boolean
  timestamp: Timestamp
  description: string
  userId: string
  caseName: string
  geoLocation: string
  done: boolean
  id: string
  parentActivityID: string
  first: boolean
}

And here is the relevant code to the AddCase modal.

const [newCase, setNewCase] = useState<ICases>()

  const updateCase = (key: keyof ICases, value: string) => {
    const updatedCase = newCase ? { ...newCase } : ({} as ICases)
    updatedCase[key] = value
    setNewCase(updatedCase)
  }

2

Answers


  1. The error is occurring because you are trying to assign a string value to a property of type Material[], Timestamp, boolean, or number which is not possible. To resolve the issue, you need to cast the value parameter to the correct type before assigning it to the updatedCase object. For example, you could use a switch statement to determine the correct type based on the key parameter:

    const updateCase = (key: keyof ICases, value: string) => {
        const updatedCase = newCase ? { ...newCase } : ({} as ICases)
        switch (key) {
            case 'materials':
                updatedCase.materials = value as Material[]
                break
            case 'finalActivity':
                updatedCase.finalActivity = value === 'true'
                break
            case 'existingCase':
                updatedCase.existingCase = value === 'true'
                break
            case 'timestamp':
                updatedCase.timestamp = value as Timestamp
                break
            case 'done':
                updatedCase.done = value === 'true'
                break
            default:
                updatedCase[key] = value
        }
        setNewCase(updatedCase)
    }
    

    Note: This is just one way to resolve the issue. Depending on your specific use case, you may need to handle the casting in a different way.

    Login or Signup to reply.
  2. Your issue is that the key in keyof does not necessarily have a value that’s a string. To fix this, we can get just the keys that have a string value.

    // https://stackoverflow.com/a/54520829/6911703
    type KeysMatching<T, V> = {[K in keyof T]-?: T[K] extends V ? K : never}[keyof T];
    
    const updateCase = (key: KeysMatching<ICases, string>, value: string) => {
      const updatedCase = newCase ? { ...newCase } : ({} as ICases)
      updatedCase[key] = value
      setNewCase(updatedCase)
    }
    

    Or, if you want value to match the type of the key, you can do this:

    const updateCase = <K extends keyof ICases>(key: K, value: ICases[K]) => {
      const updatedCase = newCase ? { ...newCase } : ({} as ICases)
      updatedCase[key] = value
      setNewCase(updatedCase)
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search