ค้นหาเว็บไซต์

javascript - ประเภท '{ children: Element; }' ไม่มีคุณสมบัติใดที่เหมือนกับประเภท 'IntrinsicAttributes' - React 18.2.0


ฉันมีคำถาม ฉันกำลังเรียน React กับ TypeScript โดยใช้หนังสือเรียน - fullstack react with typescript ตอนนี้ฉันอยู่ที่แอปแรก - การโคลน Trello

ฉันเจอบั๊กที่ฉันกำลังหาวิธีแก้ไขได้ยาก

ฉันได้รับข้อผิดพลาดนี้จาก AppStateContext

Type '{ children: Element; }' has no properties in common with type 'IntrinsicAttributes'

นี่คือบล็อกที่มันถูกกำหนด: AppStateContext.tsx

export const AppStateProvider: FC = ({ children }: React.PropsWithChildren<{}>) => {
  const [state, dispatch] = useImmerReducer(appStateReducer, appData)
  const { lists } = state

  const getTasksByListId = (id: string) => {
    return lists.find((list) => list.id === id)?.tasks || []
  }

  return (
    <AppStateContext.Provider value={{ lists, getTasksByListId, dispatch }}>
      {children}
    </AppStateContext.Provider>
  )
}

นี่คือบล็อกที่ถูกเรียก: index.tsx

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
    <AppStateProvider>
      <App />
    </AppStateProvider>
);

ข้อผิดพลาดเกิดจากที่ฉันเรียกในไฟล์ index.tsx

ฉันขอบคุณสำหรับความช่วยเหลือล่วงหน้าเป็นอย่างมาก เวอร์ชันของ React คือ 18.2.0

คำตอบ #1

คุณจำเป็นต้องลบประเภท FC ที่ชัดเจนสำหรับ AppStateProvider ออก

ดูตัวอย่างที่ทำให้เข้าใจง่ายนี้:

interface FunctionComponent<P = {}> {
    (props: P, context?: any): ReactElement<any, any> | null;
}

อย่างที่คุณอาจสังเกตเห็น, FunctionComponent เป็นเวอร์ชันที่เรียบง่ายขึ้น (ลบ props ที่ไม่เกี่ยวข้องกับคำถามของคุณออก) ของ FC.

Generic P แทนค่าอาร์กิวเมนต์ props หาก generic P ไม่มี property children คุณจะไม่สามารถใช้มันได้ แท้จริงแล้วคุณสามารถใช้ได้เฉพาะ property ที่ประกาศใน generic P เท่านั้น

โปรดทราบว่าคุณได้ใช้เพียง FC ซึ่งหมายความว่า P generic ถูกแทนที่ด้วย {} ดังนั้นคุณจะไม่สามารถให้คุณสมบัติใด ๆ กับคอมโพเนนต์ React ได้

ดูนี่:

type Fn<P = 'no properties'> = (props: P) => void

const fn: Fn = (props) => {
    props // no properties
 }

props มีชนิด 'no properties' และคุณไม่อนุญาตให้แทนที่ด้วยชนิดอื่น:

// errpr
const fn: Fn = (props:number) => {
    props // no properties
 }

ตัวอย่างของคุณค่อนข้างแตกต่าง เพราะประเภทของ TypeScript {} เป็นประเภทที่ซับซ้อน เนื่องจากทุกอย่างใน JavaScript เป็น object ประเภทใด ๆ (ไม่แน่ใจ 100%) สามารถกำหนดค่าให้กับ {} ได้ นี่คือเหตุผลที่คุณไม่พบข้อผิดพลาดเมื่อใช้ React.PropsWithChildren<{}> สำหรับ props อย่างไรก็ตาม การใช้ React.PropsWithChildren<{}> จะไม่ส่งผลกระทบต่อประเภท AppStateProvider เพราะเมื่อคุณเรียกใช้ มันจะคาดหวังเพียง {} เป็น properties เท่านั้น

โดยเป็นกฎทั่วไป คุณสามารถใช้ทั้งชนิดของฟังก์ชันทั้งหมดอย่างชัดเจนและหลีกเลี่ยงการใช้ชนิดของอาร์กิวเมนต์ หรือเพียงแค่ใช้ชนิดสำหรับอาร์กิวเมนต์เท่านั้น

อันนี้ก็ได้:

type Fn<P = 'no properties'> = (props: P) => void

const fn: Fn = (props) => {
    props // no properties
 }

หรือ

const fn = (props:'no properties') => {
    props // no properties
 }

ป.ล. ใน React 17.*, FC มี children type ดูบทความนี้

คำตอบ #2

ข้อผิดพลาดโดยพื้นฐานแล้วบอกคุณว่าประเภทของ children (ซึ่งคือ Elements) ไม่มีการทับซ้อนกับประเภทที่คุณกำหนดใน TypeScript (React.PropsWithChildren<{}>) วิธีที่ง่ายในการแก้ปัญหาคือการเปลี่ยนไฟล์ AppStateContext.tsx เป็นอะไรทำนองนี้:

export const AppStateProvider: FC = ({ children }: {children:Elements) => {
...

อย่างไรก็ตาม ถ้าคุณต้องการฝึกฝนการเขียนโค้ดที่สะอาดจริง ๆ และใช้ React.PropsWithChildren นี่คือตัวเก็บข้อมูลพร้อมตัวอย่างการใช้งาน: https://github.com/KishorNaik/Sol_PropsWithChildren_React

หวังว่านี่จะช่วยได้