реагировать-выбор асинхронных загрузок с помощью TypeScript

#javascript #reactjs #typescript #react-select

Вопрос:

Я конвертирую существующее приложение react в typescript, и у меня возникли проблемы с тем, чтобы асинхронный выбор react loadOptions правильно анализировался как 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,
    }
}
 

Ошибка в том, что

     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
 

Я не понимаю, где мне нужно объявить тип возвращаемого loadOptions значения, чтобы он работал должным образом.

Ответ №1:

Если это фактический код вашей loadOptions функции, то с ним есть пара проблем:

  • Он не возвращает никакого значимого значения (он возвращает undefined , и учет async его имеет тип возврата Promise<void> )
  • Он не оказывает побочных эффектов

С практической стороны это вообще ничего полезного не делает и просто выбрасывает данные об ответах.


Чтобы исправить это, вы можете воспользоваться одним из следующих подходов:

  1. Верните что-нибудь полезное. Затем вам нужно указать тип возвращаемого значения функции:
 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. Или выполнить побочный эффект:
 // 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);
        }))
    });
};
 

Комментарии:

1. Спасибо вам за ваше подробное объяснение. На самом деле я возвращал данные из вызова axios, я просто вставил неправильную версию в свой вопрос, так как пробовал много разных вещей!