ریاکتجیاس - متریال-یوآی - تایپاسکریپت - تکمیل خودکار عمومی


با TypeScript، من در تلاش هستم یک کامپوننت AutoComplete از Material-UI ایجاد کنم که مقدار ورودی را بر اساس نام ویژگی یک شی دریافت کند -> obj[key]

با این حال، prop getOptionLabel خطای زیر را نشان میدهد:

نوع '(option: T) => T[keyof T] | ""' قابل اختصاص به نوع '(option: T) => string' نیست.

پروپ یک رشته انتظار دارد، و من میفهمم که مقدار ویژگی شی ممکن است رشته نباشد.

سؤال: چرا این خطا بر اساس کد زیر رخ میدهد و چگونه میتوانم آن را حل کنم؟

لینک کدسندباکس: https://codesandbox.io/s/mui-ts-generic-autocomplete-o0elk?fontsize=14&hidenavigation=1&theme=dark

همچنین کد اصلی در صورتی که لینک کدسندباکس در مقطعی مشکل اصلی را نشان ندهد:

import * as React from "react";
import { Autocomplete } from "@material-ui/lab";
import { TextField } from "@material-ui/core";

export const isString = (item: any): item is string => {
  return typeof item === "string";
};

type AutoCompleteFieldProps<T> = {
  selectValue: keyof T;
  options: T[];
};

// Top films as rated by IMDb users. http://www.imdb.com/chart/top
const topFilms = [
  { title: "The Shawshank Redemption", year: 1994 },
  { title: "The Godfather", year: 1972 },
  { title: "The Godfather: Part II", year: 1974 },
  { title: "The Dark Knight", year: 2008 },
  { title: "12 Angry Men", year: 1957 },
  { title: "Schindler's List", year: 1993 },
  { title: "Pulp Fiction", year: 1994 }
];

const AutoCompleteField = <T extends {}>({
  selectValue,
  options
}: AutoCompleteFieldProps<T>): React.ReactElement => {
  return (
    <Autocomplete<T>
      id={name}
      options={options}
      fullWidth
      // Error here
      getOptionLabel={(option) =>
        isString(option[selectValue]) ? option[selectValue] : ""
      }
      renderInput={(params) => (
        <TextField {...params} label="demo autocomplete" />
      )}
    />
  );
};

// error:
// Type '(option: T) => T[keyof T] | ""' is not assignable to type '(option: T) => string'.

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <AutoCompleteField<{ title: string; year: number }>
        options={topFilms}
        selectValue="title"
      />
    </div>
  );
}

پیشاپیش ممنون!

پاسخ شماره ۱

من کد تو را با موفقیت اجرا کردم

getOptionLabel={(option) =>{
    const val = option[selectValue];
    return isString(val) ? val : ""
  }

به نظر میرسد محافظ نوع بدون استفاده مستقیم از یک متغیر به خوبی کار نکرد.

پاسخ شماره ۲

نوع option را any قرار دادن (option: any) جواب داد

getOptionLabel={(option: any) =>
  isString(option[selectValue]) ? option[selectValue] : ""
}