reactjs - نوع بازگشتی useMemo اشتباه است، اما tsc خطا نشان نخواهد داد؟


const labelTypeMap = useMemo<Record<'between' | 'inner', string>>(
  () => ({
    between: formatMessage({ id: 'addGroup' }),
    inner: '+',
    aaa: 123, // no error here
  }),
  []
);

به عنوان کد، هیچ خطایی در aaa وجود ندارد، حتی اگر با نوع بازگشتی useMemo مطابقت نداشته باشد. هر کمکی بسیار قدردانی خواهد شد.

پاسخ شماره ۱

در اینجا یک نسخه سادهشده است که هنوز مشکل را نشان میدهد:

const labelTypeMap: Record<"between" | "inner", string> = (() => ({
    between: "xxx",
    inner: "+",
    aaa: 123,
}))();

مشکل این است که تایپاسکریپت، به طور کلی، اجازهٔ وجود خصوصیات اضافی در اشیاء را میدهد. به هر حال، یک شیء با خصوصیات اضافی سازگار با نوع پایه است (از نظر شیءگرایی). شگفتیها تنها زمانی رخ میدهند که از ویژگیهای درونیابی پویا مانند Object.keys و موارد مشابه استفاده کنید.

تنها استثنا برای این انعطافپذیری زمانی است که بخواهید یک شیء صریح را مستقیماً اختصاص دهید:

const labelTypeMap: Record<"between" | "inner", string> = {
    between: "xxx",
    inner: "+",
    aaa: 123, // Error as expected
};

حالا طبق انتظار شکایت خواهد کرد.

پس یکی از راهحلهای ممکن برای مشکل شما این است:

const labelTypeMap = useMemo(() => {
    const result: Record<"between" | "inner", string> = {
        between: "xxx",
        inner: "+",
        aaa: 123, // Error as expected
    };

    return result;
}, []);

این هم کار میکند:

const labelTypeMap = useMemo(
    (): Record<"between" | "inner", string> => ({
        between: "xxx",
        inner: "+",
        aaa: 123, // Error as expected
    }),
    [],
);