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
