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

reactjs - วิธีที่ถูกต้องในการจัดการไฟล์ประกาศที่ไม่ได้กำหนด (index.d.ts)


ฉันได้รับข้อผิดพลาดดังต่อไปนี้

error TS7016: Could not find a declaration file for module 'react-native-camera'. '/Users/ilja/Documents/Repositories/blok/node_modules/react-native-camera/index.js' implicitly has an 'any' type.
  Try `npm install @types/react-native-camera` if it exists or add a new declaration (.d.ts) file containing `declare module 'react-native-camera';`

เป็นวิธีแก้ปัญหาอย่างรวดเร็ว ฉันสร้างไฟล์ typings/index.d.ts (ไม่มี @types/react-native-camera) ที่รูทของโปรเจกต์ของฉันและเพิ่มเนื้อหาลงไปด้วย

declare module 'react-native-camera';

แล้วในไฟล์ tsconfig ของฉันฉันได้เพิ่มมันลงใน type roots ของฉันแบบนี้

"typeRoots": ["node_modules/@types", "./typings"],

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

แก้ไข, tsconfig ของฉันเต็ม ๆ มีลักษณะดังนี้

{
  "compilerOptions": {
    "target": "ES6",
    "module": "commonjs",
    "lib": ["es7"],
    "allowJs": true,
    "checkJs": true,
    "jsx": "react-native",
    "removeComments": true,
    "outDir": "./dist",
    "typeRoots": ["node_modules/@types", "./typings"],
    "experimentalDecorators": true,
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "allowSyntheticDefaultImports": true,
    "strict": true
  },
  "exclude": ["./node_modules", "./android", "./ios", "./assets", "./__tests__", "./dist"],
  "include": ["./src"]
}

คำตอบ #1

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

ฉันได้สร้างโครงสร้างที่คุณอธิบายไว้และพบข้อผิดพลาดเดียวกับที่คุณพบ จากนั้นฉันสร้าง react-native-camera ภายใต้ typings และย้าย index.d.ts ไปที่นั่น ดังนั้นฉันจึงได้โครงสร้างดังนี้:

typings/
└── react-native-camera
    └── index.d.ts

ด้วยโครงสร้างนี้ การคอมไพล์ทำงานได้อย่างราบรื่น

การใช้โครงสร้างไดเรกทอรี typings นั้นก็สามารถทำได้ ถ้าคุณต้องการโครงสร้างแบบนั้น สำหรับบางโปรเจกต์ฉันใช้ไดเรกทอรี typings สำหรับโปรเจกต์อื่น ๆ ฉันชอบอะไรที่ง่ายกว่า: ใช้ไฟล์ .d.ts ในต้นไม้ซอร์สโค้ดที่ประกาศทุกอย่างที่ต้องประกาศ ดังนั้นถ้าฉันเริ่มจากคำอธิบายที่คุณให้มา แต่ลบ typings และเพิ่ม src/definitions.d.ts ที่มี

declare module 'react-native-camera';

แล้วโค้ดก็คอมไพล์ได้อย่างปกติดี

มันเป็นเรื่องของความชอบส่วนบุคคลว่าใช้แบบไหน โดยปกติเมื่อโปรเจกต์มีความซับซ้อนมากจน src/definitions.d.ts จัดการยากหรือเข้าใจยาก ผมจะย้ายไปใช้ไดเรกทอรี typings

คำตอบ #2

จากเอกสาร flowtype ในส่วนของคำจำกัดความของห้องสมุด ระบุว่า:

libdef คือไฟล์พิเศษที่บอก Flow เกี่ยวกับลายเซ็นของประเภทของโมดูลบุคคลที่สามเฉพาะหรือชุดโมดูลที่แอปพลิเคชันของคุณใช้งาน หากคุณคุ้นเคยกับภาษาที่มีไฟล์หัวเรื่อง (เช่น C++) คุณสามารถคิดว่า libdefs เป็นแนวคิดที่คล้ายกัน

แนวทางปฏิบัติที่ดีที่สุดทั่วไป

พยายามจัดทำ libdef สำหรับไลบรารีของบุคคลที่สามแต่ละตัวที่โครงการของคุณใช้งาน

ดูใน .flowconfig ที่โฟลเดอร์หลัก คุณจะเห็นว่ามันถูกกำหนดไว้ที่นั่นแล้ว

[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow
./libdefs.js

จากนั้นมองหา libdefs.js ในโฟลเดอร์หลัก มันควรจะอยู่ตรงนั้น หรือไม่ก็สร้างไฟล์ขึ้นมาเองก็ได้

สำหรับทุกโมดูล ให้ประกาศมันดังตัวอย่างด้านล่าง ยกตัวอย่าง rxjs:

declare module 'rxjs' { declare var exports: any; }

นี่คือวิธีแนะนำอย่างเป็นทางการ ไม่จำเป็นต้องแก้ไข index.d.ts

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