Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
213 views
in Technique[技术] by (71.8m points)

reactjs - Return an Array of Object and Function Typescript

First of all, the problem I'm facing:

I worked a few months with a self made React Hook with vanilla JS, code bellow:

import { useState } from 'react';

const useForm = (initialValues) => {
    const [state, setState] = useState(initialValues);

    return [
        state,
        (e) => {
            if (typeof e.target !== 'undefined') {
                setState({
                    ...state,
                    [e.target.name]: e.target.value,
                });
            } else {
                setState({ ...e });
            }
        },
    ];
};

export default useForm;

Right now, I decided to go Typescript. However could not convert that hook. I got like everything in place but the return interface/type. Same hook Typescript version (with a wrong return type):

import { useState, FormEvent } from 'react';

interface ReturnProps {
  [index: number]: Record<string, unknown>;
  [index: number]: (e: FormEvent<HTMLInputElement>) => void;
}

const useForm = (initialValues: Record<string, unknown>): ReturnProps => {
  const [state, setState] = useState(initialValues);

  return [
    state,
    (e: FormEvent<HTMLInputElement>): void => {
      if (typeof e.currentTarget !== 'undefined') {
        setState({
          ...state,
          [e.currentTarget.name]: e.currentTarget.value,
        });
      } else {
        setState({ ...e });
      }
    },
  ];
};

export default useForm;

Question is: How to return the right type in this situation?

question from:https://stackoverflow.com/questions/65890273/return-an-array-of-object-and-function-typescript

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You just need to fix the ReturnProps type:

interface ReturnProps {
  [index: number]: Record<string, unknown>;
  [index: number]: (e: FormEvent<HTMLInputElement>) => void;
}

You can't have two duplicate index signatures like that.

Since the first element in the returned array will be the Record, and the second will be the callback, use a tuple instead:

type ReturnProps = [
    Record<string, unknown>,
    (e: FormEvent<HTMLInputElement>) => void
]

You could even omit the ReturnProps entirely, and TS will still be able to infer the proper type:

const useForm = (initialValues: Record<string, unknown>) => {

(Letting TS infer types automatically when possible can really cut down on type noise that may distract from the main logic of your script.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...