0

I have this type:

interface MyType {
   name: string
   age: number
   friend: Person
}

and consider this state:

const [myState, setMyState] = useState<MyType>({.....})

and I have this function that changes a filed inside useState:

const handleChange = (filed: keyof MyType, value: unknown) => {
   setMyState({
      ...myState,
      [field]: value
   })
}

how can I use generics or some other work around to type the value argument in the above function?
I expect my handleChange function to throw error when wrong value is passed to a field:

handleChange("name", 5);

1 Answer 1

1

You need add generic for field argument:

import React, { useState } from 'react'

type Person = {
  tag: 'Person'
}
interface MyType {
  name: string
  age: number
  friend: Person
}

declare const DEFAULT_STATE: MyType

const App = () => {
  const [myState, setMyState] = useState<MyType>(DEFAULT_STATE)

  const handleChange = <Field extends keyof MyType>(field: Field, value: MyType[Field]) => {
    setMyState({
      ...myState,
      [field]: value
    })
  }

  handleChange('name', 'John') // ok
  handleChange('age', 'five') // expected error

}

Playground

Sign up to request clarification or add additional context in comments.

1 Comment

wish I could up-vote this twice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.