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

reactjs - การทำ Mock react-router-dom สำหรับ useHistory hook ทำให้เกิดข้อผิดพลาดดังต่อไปนี้ - TS2698: ประเภทสเปรดสามารถสร้างได้จากประเภทวัตถุเท่านั้น


ฉันกำลังพยายามจำลอง react-router-dom ในหนึ่งในกรณีทดสอบของฉันเพื่อให้ hook useHistory ทำงานในทดสอบของฉัน ฉันตัดสินใจใช้ jest.mock เพื่อจำลองโมดูลทั้งหมด และ jest.requireActual เพื่อเก็บคุณสมบัติอื่น ๆ ที่ฉันอาจไม่ต้องการจำลอง

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useHistory: () => ({
    location: {
      pathname: '/list',
    },
  }),
}));

นี่จริงๆ แล้วมาจากหนึ่งในโซลูชันที่ได้รับความนิยมสูงต่อคำถามต่อไปนี้: จะจำลอง useHistory hook ใน jest ได้อย่างไร?

อย่างไรก็ตาม คอมไพเลอร์ TypeScript กำลังแสดงข้อผิดพลาดดังต่อไปนี้ในบรรทัดต่อไปนี้ ...jest.requireActual('react-router-dom'),

TS2698: ประเภทการกระจายสามารถสร้างได้จากประเภทวัตถุเท่านั้น

ที่น่าสนใจคือ ฉันเจอปัญหานี้เฉพาะหลังจากอัปเดต jest และ ts-jest เป็นเวอร์ชันล่าสุด (jest v26) ฉันไม่เจอปัญหาเหล่านี้เลยเมื่อฉันใช้ jest 24.x.x

"@types/jest": "^26.0.4",
"jest": "^26.1.0",
"ts-jest": "^26.1.1",

มีใครรู้วิธีแก้ปัญหานี้สำหรับเวอร์ชันล่าสุดของ jest ไหม?

คำตอบ #1

jest.requireActual ส่งค่าประเภท unknown ซึ่งไม่สามารถกระจายได้

ประเภทที่ถูกต้องคือ:

import * as ReactRouterDom from 'react-router-dom';

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom') as typeof ReactRouterDom,
  useHistory: ...,
}));

วิธีแก้ไขอย่างรวดเร็วคือ any:

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom') as any,
  useHistory: ...,
}));

มันถือว่าเป็นที่ยอมรับได้เพราะในกรณีนี้มันไม่ได้ทำให้ความปลอดภัยของชนิดข้อมูลเสียหาย

เนื่องจาก react-router-dom เป็นโมดูล ES วิธีที่ถูกต้องมากขึ้นในการจำลองมันคือ:

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom') as any,
  __esModule: true,
  useHistory: ...,
}));

บทความที่เกี่ยวข้อง