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

reactjs - ตรวจสอบชนิดของคอมโพเนนต์ที่ส่งเป็น props ใน Typescript React


ฉันมีคำถามเกี่ยวกับการตรวจสอบประเภทในคอมโพเนนต์ React ที่ส่งเป็น props: เราจะตรวจสอบประเภทเพื่อให้แน่ใจว่าเราส่งเป็น props เฉพาะคอมโพเนนต์ที่อนุญาตได้อย่างไร?

ให้ฉันอธิบายมัน เรามีส่วนประกอบที่เราต้องการส่งต่อ:

type DummyProps = {
  name: string;
};

const Dummy = ({ name }: DummyProps) => {
  return (<div>{name}</div>);
}

และคอมโพเนนต์ที่เราต้องการฉีดคอมโพเนนต์ Dummy เข้าไป (และมีการตรวจสอบประเภทแบบสถิต ดังนั้นเราไม่สามารถส่งคอมโพเนนต์อื่นใดได้):

type DummyWrapperProps = {
  dummy: ReactComponentElement<typeof Dummy>;
};

const DummyWrapper = ({ dummy }: DummyProps) => {
  return (<div>{name}</div>);
}

ตอนนี้ หากเราทำการเรียก DummyWrapper แม้ว่าจะได้กำหนดประเภทของ prop dummy เป็น ReactComponentElement<typeof Dummy> อย่างชัดเจน แต่ดูเหมือนว่าเราสามารถส่ง ReactElement ใดก็ได้ไม่ว่าจะมี props/ประเภทอะไร:

const dummyElement = <Dummy name='dummy' />
const otherElement = <Other /> //this component is defined elsewhere

<DummyWrapper dummy={dummyElement} /> // This works
<DummyWrapper dummy={otherElement} /> // This also works

ฉันก็ได้พยายามทำสิ่งที่คล้ายกันโดยมีการกำหนด DummyWrapperProps ด้วย React.ReactElement, React.FC เป็นต้น แต่ก็ยังได้ผลลัพธ์เหมือนเดิม: การตรวจสอบประเภทแบบคงที่ของ TypeScript ไม่เตือนเกี่ยวกับคอมโพเนนต์/องค์ประกอบที่ถูกส่งมาไม่ตรงกับประเภทที่คาดไว้

ฉันสมมติว่าปัญหานี้ยังขยายไปถึง children ด้วย เพราะมันแทบจะเหมือนกัน: คุณกำลังส่งต่อองค์ประกอบต่าง ๆ

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

คำตอบ #1

ฉันคิดว่าคุณไม่สามารถทำสิ่งนี้ในลักษณะนั้นได้ เพราะประเภทของการสร้างอินสแตนซ์ขององค์ประกอบใด ๆ จะเป็น JSX.Element และคุณอาจสามารถทำสิ่งนี้แทนได้:

const DummyWraper = ({ dummy: D, name }: { dummy: FC<DummyProps> } & DummyProps) => (
  <div>
    <D name={name} />
  </div>
)

ที่เกิดขึ้น:

type DummyProps = {
  name: string
}

const Other: FC<{ some: number }> = () => <div>1</div>

const Dummy: FC<DummyProps> = ({ name }) => {
  return <div>{name}</div>
}

const dummyElement = <Dummy name="dummy" />
const otherElement = <Other />

const b = <DummyWraper dummy={Other} name="dummy" />
const c = <DummyWraper dummy={Dummy} name="dummy" />

ระวังประเภท FC<{}> สำหรับ Other เพราะ {} ใน typescript ทำงานเหมือนกับ any สำหรับวัตถุ