简体   繁体   中英

react-select async loadOptions with TypeScript

I'm converting an existing react app to typescript, and I'm having trouble getting the react-select async loadOptions to parse correctly as typescript.

export type userType = {
    loginId: string,
    firstName: string,
    lastName: string,
    email: string,
}

<AsyncSelect
    id={n.id}
    name={n.id}
    isClearable={true}
    onBlur={handleBlur}
    onChange={onChange}
    placeholder={"Search by name, email or login ID"}
    value={input}
    className={input_class}
    loadOptions={loadOptions}
/>


const loadOptions = async (inputText: string, callback: any) => {
    axios.get(`myAPI_URI`)
        .then((response) => {
            let data: userType[] = response.data.results;
            return data.map(result => {
                return labelFormatter(result)
            })
        });
}

const labelFormatter = (i: any) => {
    return {
        label: i.loginId + ' - ' + i.firstName + ' ' + i.lastName + ' - ' + i.email,
        value: i.loginId,
    }
}

The error is

    No overload matches this call.
Overload 1 of 2, '(props: Props<filteredOptionType, false, GroupTypeBase<filteredOptionType>> | Readonly<Props<filteredOptionType, false, GroupTypeBase<...>>>): Async<...>', gave the following error.
    Type '(inputText: string, callback: any) => Promise<void>' is not assignable to type '(inputValue: string, callback: (options: readonly (filteredOptionType | GroupTypeBase<filteredOptionType>)[]) => void) => void | Promise<...>'.
    Type 'Promise<void>' is not assignable to type 'void | Promise<readonly (filteredOptionType | GroupTypeBase<filteredOptionType>)[]>'.
        Type 'Promise<void>' is not assignable to type 'Promise<readonly (filteredOptionType | GroupTypeBase<filteredOptionType>)[]>'.
        Type 'void' is not assignable to type 'readonly (filteredOptionType | GroupTypeBase<filteredOptionType>)[]'.
Overload 2 of 2, '(props: Props<filteredOptionType, false, GroupTypeBase<filteredOptionType>>, context: any): Async<filteredOptionType, false, GroupTypeBase<...>>', gave the following error.
    Type '(inputText: string, callback: any) => Promise<void>' is not assignable to type '(inputValue: string, callback: (options: readonly (filteredOptionType | GroupTypeBase<filteredOptionType>)[]) => void) => void | Promise<...>'.  TS2769

I'm not understanding where I need to declare the return type for loadOptions to work as expected.

If that is the actual code of your loadOptions function then there are a couple of issues with it:

  • It does not return any meaningful value (it returns undefined , and accounting for async it has return type Promise<void> )
  • It performs no side effects

From the practical side it does nothing usefull at all and just throwing away response data.


To fix that you may take one of the following approaches:

  1. Return something useful. Then you have to annotate return type of the function:
import { OptionTypeBase } from "react-select/src/types"

const labelFormatter = (i: userType): OptionTypeBase => {
  return {
      label: i.loginId + ' - ' + i.firstName + ' ' + i.lastName + ' - ' + i.email,
      value: i.loginId,
  }
}

// add `return` keyword
const loadOptions = async (
    inputText: string, 
    callback: any
): Promise<OptionTypeBase[]> => {
    return axios.get(`myAPI_URI`)
        .then((response) => {
            let data: userType[] = response.data.results;
            return data.map(result => {
                return labelFormatter(result)
            })
        });
}

// or remove curly braces
const loadOptions = async (
    inputText: string, 
    callback: any
): Promise<OptionTypeBase[]> => 
    axios.get(`myAPI_URI`)
        .then((response) => {
            let data: userType[] = response.data.results;
            return data.map(result => {
                return labelFormatter(result)
            })
        });
  1. Or perform side effect:
// no `async` keyword. and using callback inside the function body
const loadOptions = (
    inputText: string,
    callback: (options: OptionTypeBase[]) => void
): void => {
    axios.get(`myAPI_URI`).then((response) => {
        let data: userType[] = response.data.results;
        callback(data.map((result) => {
            return labelFormatter(result);
        }))
    });
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM