Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flow type - Index signature declaring the expected key / value type is missing in GenericType

I'm having issues to access a object property dynamically with a Generic Type . Here is the code:

import React, { useState } from 'react'

function useForm<FormValues>(initialValues: FormValues) {
    const [formValues, setFormValues] = useState<FormValues>(initialValues)

    function getValue(fieldName: string) {
        return formValues[fieldName]
    }
}

Here is the error:

7: return formValues[fieldName] ^ Cannot get formValues[fieldName] because an index signature declaring the expected key / value type is missing in FormValues [1]. References: 4: const [formValues, setFormValues] = useState(initialValues) ^ [1]

Here is the Try Flow link: https://flow.org/try/#0JYWwDg9gTgLgBAJQKYEMDGMA0cDecCuAzkgMowoxJwC+cAZlBCHAORSoYsBQXd+AdhmAR+BYgDFoIADySoIAGooANviSEAfAApg-YDGAqlq9QC44cxSrWEAlLi4BINCMLwA2nSnGb2YjEsfdQBdOABeMVJySllva3VtXX1DZSC7LjhMuAysvkEDETgAcyQYIK06YCRlABMAORQQJHM3KF0i+xwczMd2GHwoUS95NM8q2oam4O6aLmogA

Thanks for the help.

like image 292
Bruno Quaresma Avatar asked May 17 '19 13:05

Bruno Quaresma


1 Answers

Lets simplify the question:

I. useStatehave the following type:

export function useState<S>(
  initialState: (() => S) | S,
): [S, Dispatch<BasicStateAction<S>>] {}

II. For us is important returned type:

export function simpleUseState<S>(initialState: S): [S] {}

III. Simplified version:

declare var simpleUseState: <S>(initialState: S)=> [S];

function useForm<FormValues>(initialValues: FormValues, fieldName: string) {
    const [formValues] = simpleUseState<FormValues>(initialValues)

    return formValues[fieldName];
}

And we have the same error

Because a Generic type has no key/value signature, for example it can be a number or null - we need to add constraints on Generic:

import React, { useState } from 'react'

function useForm<FormValues: {[string]: string}>(initialValues: FormValues) {
//                         ^ constraint
    const [formValues, setFormValues] = useState<FormValues>(initialValues)

    function getValue(fieldName: string) {
        return formValues[fieldName]
    }
}
like image 103
Buggy Avatar answered Oct 30 '22 22:10

Buggy