คุณจะสร้างไฟล์คำจำกัดความ "typings" จากไลบรารี JavaScript ที่มีอยู่ได้อย่างไร


193

ฉันใช้ห้องสมุดจำนวนมากทั้งของฉันและของบุคคลที่สาม ฉันเห็นไดเรกทอรี "typings" มีบางอย่างสำหรับ Jquery และ WinRT ... แต่พวกเขาจะสร้างอย่างไร

คำตอบ:


232

มีตัวเลือกไม่กี่ตัวเลือกให้คุณขึ้นอยู่กับห้องสมุดที่มีปัญหาวิธีเขียนและระดับความแม่นยำที่คุณต้องการ ลองตรวจสอบตัวเลือกโดยเรียงตามลำดับความต้องการ

อาจจะมีอยู่แล้ว

ตรวจสอบ DefinitelyTyped ทุกครั้ง ( https://github.com/DefinitelyTyped/DefinitelyTyped ) ก่อน นี่คือ repo ชุมชนที่มีไฟล์. d.ts นับพันนับพันและน่าจะเป็นสิ่งที่คุณใช้อยู่แล้ว คุณควรตรวจสอบ TypeSearch ( https://microsoft.github.io/TypeSearch/ ) ซึ่งเป็นเอ็นจิ้นการค้นหาสำหรับไฟล์. d.ts ที่เผยแพร่โดย NPM; สิ่งนี้จะมีคำจำกัดความมากกว่าปกติเล็กน้อย บางโมดูลยังจัดส่งคำจำกัดความของตนเองเป็นส่วนหนึ่งของการแจกแจง NPM ดังนั้นลองดูว่าเป็นกรณีนี้หรือไม่ก่อนที่จะพยายามเขียนด้วยตัวคุณเอง

บางทีคุณไม่ต้องการ

TypeScript ตอนนี้รองรับการ--allowJsตั้งค่าสถานะและจะทำให้การอนุมานบนพื้นฐานของ JS ในไฟล์. js คุณสามารถลองรวมไฟล์. js ในการคอมไพล์ของคุณพร้อมกับการ--allowJsตั้งค่าเพื่อดูว่าสิ่งนี้ให้ข้อมูลประเภทที่ดีพอหรือไม่ TypeScript จะรับรู้สิ่งต่าง ๆ เช่นคลาสสไตล์ ES5 และความคิดเห็น JSDoc ในไฟล์เหล่านี้ แต่อาจสะดุดเมื่อไลบรารีเริ่มต้นตัวเองในลักษณะแปลก ๆ

เริ่มต้นด้วย --allowJs

หาก--allowJsให้ผลลัพธ์ที่ดีและคุณต้องการเขียนไฟล์คำนิยามที่ดีกว่าด้วยตัวคุณเองคุณสามารถใช้ร่วม--allowJsกับ--declarationเพื่อดู "เดาที่ดีที่สุด" ของ TypeScript ได้ที่ประเภทของห้องสมุด สิ่งนี้จะให้จุดเริ่มต้นที่ดีแก่คุณและอาจดีเท่ากับไฟล์ที่เขียนด้วยมือหากความคิดเห็น JSDoc นั้นเขียนได้ดีและคอมไพเลอร์ก็สามารถค้นหาได้

เริ่มต้นกับ dts-gen

หาก--allowJsไม่ได้ผลคุณอาจต้องการใช้ dts-gen ( https://github.com/Microsoft/dts-gen ) เพื่อรับจุดเริ่มต้น เครื่องมือนี้ใช้รูปร่างรันไทม์ของวัตถุเพื่อระบุคุณสมบัติที่มีอยู่ทั้งหมดอย่างถูกต้อง ในด้านบวกสิ่งนี้มีความแม่นยำมาก แต่เครื่องมือยังไม่สนับสนุนการคัดลอกความคิดเห็น JSDoc เพื่อเติมประเภทเพิ่มเติม คุณทำเช่นนี้เพื่อ:

npm install -g dts-gen
dts-gen -m <your-module>

สิ่งนี้จะสร้างyour-module.d.tsในโฟลเดอร์ปัจจุบัน

กดปุ่มเลื่อนซ้ำ

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

declare module "foo";

ซึ่งจะช่วยให้คุณโมดูลที่มีประเภท หากคุณมีโลกที่คุณต้องการจัดการในภายหลังเพียงแค่เขียนimport"foo"any

declare const foo: any;

ซึ่งจะทำให้คุณมีfooตัวแปร


25
อุ๊ย ... นั่นจะเป็นอุปสรรคสำคัญสำหรับการเข้าในหลายกรณี มันจะดีถ้ามีเครื่องมือที่สามารถส่งออกอย่างน้อย "ทายผลที่ดีที่สุด" ตามการอนุมานประเภท แม้ว่าสิ่งเหล่านี้อาจไม่เหมาะสม แต่อย่างน้อยก็สามารถปรับได้ตามเวลา
Hotrodmonkey

7
+1 - ข่าวดีเพิ่มเติม: --declarationsสร้างทั้ง.jsไฟล์และ.d.tsไฟล์ซึ่งหมายความว่าคุณจะต้องคอมไพล์เพียงครั้งเดียว
เฟนตัน

67
ชุดคำจำกัดความที่มีคุณภาพสูงสำหรับห้องสมุดยอดนิยมสามารถดูได้ที่github.com/borisyankov/DefinitelyTyped
Boris Yankov

10
เครื่องมือ 'เดาที่ดีที่สุด' จะไม่ดีไปกว่า IntelliSense ที่มีอยู่แล้วใน TypeScript ประโยชน์ของการกำหนดประเภทคือการให้ข้อมูลกับคอมไพเลอร์มากกว่าที่จะสามารถเดาได้
Boris Yankov

12
--allowJsด้วย--declarationตัวเลือกที่ไม่สามารถรวมกัน (ทดสอบใน TypeScript 1.8 และ 2.0) ถ้าฉันลองฉันจะได้รับ:error TS5053: Option 'allowJs' cannot be specified with option 'declaration'
Alexey

53

คุณสามารถใช้tsc --declaration fileName.tsเช่นไรอันอธิบายหรือคุณสามารถระบุdeclaration: trueภายใต้compilerOptionsในtsconfig.jsonสมมติว่าคุณมีอยู่tsconfig.jsonภายใต้โครงการของคุณ


4
นี่คือคำตอบที่ดีที่สุดหากคุณกำลังพัฒนาโมดูล Angular 2 ที่คุณต้องการแบ่งปัน
ดาร์ซี

ถ้าฉันลองtsc --declaration test.tsฉันได้รับข้อผิดพลาดCannot find name...สำหรับประเภทที่ฉันพยายามสร้างไฟล์การประกาศสำหรับ :) ดังนั้นฉันต้องการประเภทก่อนที่ฉันจะประกาศได้?
Kokodoko

2
@ Kokodoko คุณสามารถลองเพิ่มไฟล์declaration: trueของคุณได้tsconfig.jsonหรือไม่?
JayKan

ขอบคุณฉันแค่ต้องการสร้าง * .d.ts จาก * .ts
vintproykt

16

วิธีที่ดีที่สุดในการจัดการกับสิ่งนี้ (หากไฟล์การประกาศไม่พร้อมใช้งานในDefinitelyTyped ) คือการเขียนการประกาศสำหรับสิ่งที่คุณใช้แทนที่จะเป็นทั้งไลบรารี สิ่งนี้ช่วยลดการทำงานได้มากและนอกจากนี้คอมไพเลอร์ยังช่วยแก้ไขปัญหาที่ขาดหาย


15

ดังที่ Ryan กล่าวคอมไพเลอร์ tsc มีสวิตช์--declarationที่สร้าง.d.tsไฟล์จาก.tsไฟล์ นอกจากนี้โปรดทราบว่า (ยกเว้นข้อผิดพลาด) TypeScript ควรจะสามารถรวบรวม Javascript ได้ดังนั้นคุณสามารถส่งรหัสจาวาสคริปต์ที่มีอยู่ไปยังคอมไพเลอร์ tsc


1
ดูเหมือนว่ากำลังส่งไฟล์ * .js ไปยัง tsc สร้างข้อผิดพลาด "ไฟล์กำลังอ่านข้อผิดพลาด" angular-resource.js ": ไม่พบไฟล์" ดังนั้นคุณต้องเปลี่ยนชื่อไฟล์ * .js เป็น * .ts อย่างชัดเจนเพื่อให้สามารถใช้ tsc ได้ ดูปัญหานี้สำหรับรายละเอียดเพิ่มเติม - ฉันลองใช้สิ่งนี้กับ angularjs: typescript.codeplex.com/workitem/26
James Strachan

3
จากสิ่งที่ฉันสามารถบอกได้ tsc สามารถรวบรวม JavaScript ที่ถูกต้องใด ๆ แต่ถ้ามันไม่ถูกต้อง TypeScript (รวบรวมให้คำเตือน) จากนั้นธง --declarations ไม่ส่งออกไฟล์. d.ts ดังนั้นถ้าห้องสมุดของคุณเขียนใน TypeScript คุณ ยังคงต้องสร้างไฟล์การประกาศด้วยตนเอง
agradl


3

นี่คือ PowerShell บางตัวที่สร้างไฟล์คำจำกัดความของ TypeScript ไฟล์เดียวซึ่งเป็นไลบรารีที่มีหลาย*.jsไฟล์พร้อม JavaScript ที่ทันสมัย

.tsครั้งแรกที่เปลี่ยนส่วนขยายทั้งหมดเพื่อ

Get-ChildItem | foreach { Rename-Item $_ $_.Name.Replace(".js", ".ts") }

ขั้นที่สองใช้คอมไพเลอร์ TypeScript เพื่อสร้างไฟล์คำจำกัดความ จะมีข้อผิดพลาดมากมายในคอมไพเลอร์ แต่เราสามารถเพิกเฉยได้

Get-ChildItem | foreach { tsc $_.Name  }

สุดท้ายรวม*.d.tsไฟล์ทั้งหมดเป็นไฟล์เดียวindex.d.tsลบimportคำสั่งและลบไฟล์defaultออกจากแต่ละคำสั่งการส่งออก

Remove-Item index.d.ts; 

Get-ChildItem -Path *.d.ts -Exclude "Index.d.ts" | `
  foreach { Get-Content $_ } | `
  where { !$_.ToString().StartsWith("import") } | `
  foreach { $_.Replace("export default", "export") } | `
  foreach { Add-Content index.d.ts $_ }

สิ่งนี้ลงท้ายด้วยindex.d.tsไฟล์เดียวที่ใช้งานได้ซึ่งมีหลายคำจำกัดความ


2
ขั้นตอนที่สอง Get-ChildItem | foreach {tsc - การ ประกาศ $ _. ชื่อ} ทำงาน (เพิ่มการหายไป - การเผยแพร่ param)
Guru_07

2

ฉันจะค้นหาการแมปที่มีอยู่ของไลบรารี JS บุคคลที่สามของคุณที่รองรับ Script # หรือ SharpKit ผู้ใช้คอมไพล์เลอร์ C # ถึง. js เหล่านี้จะประสบปัญหาที่คุณเผชิญอยู่ในขณะนี้และอาจเผยแพร่โปรแกรมโอเพนซอร์ซเพื่อสแกน lib บุคคลที่สามของคุณและแปลงเป็นคลาส C # ถ้าเป็นเช่นนั้นแฮกโปรแกรมสแกนเนอร์เพื่อสร้าง TypeScript แทน C #

การแปลอินเทอร์เฟซสาธารณะ C # สำหรับ lib บุคคลที่สามของคุณเป็นคำจำกัดความ TypeScript อาจง่ายกว่าการทำเช่นเดียวกันโดยการอ่าน JavaScript ต้นทาง

ความสนใจพิเศษของฉันคือกรอบ ExtJS RIA ของ Sencha และฉันรู้ว่ามีโครงการที่เผยแพร่เพื่อสร้างการตีความ C # สำหรับ Script # หรือ SharpKit


FYI: ฉันเพิ่งสร้างไฟล์คำจำกัดความของตัวพิมพ์ครั้งแรกสำหรับ Sencha / ExtJS: github.com/andremussche/extjsTypescript/blob/master/jsondocs/
André

กรณี Camel เฮ้ฉันได้รวบรวมบล็อกในการใช้ ExtJs กับ typescript: blorkfish.wordpress.com/2013/01/28/using-extjs-with-typescript
blorkfish

2

เมื่อสร้างไลบรารีของคุณเองคุณสามารถสร้าง*.d.tsไฟล์โดยใช้ tscคำสั่ง (TypeScript คอมไพเลอร์) ดังนี้: (สมมติว่าคุณกำลังสร้างไลบรารีของคุณไปยังdist/libโฟลเดอร์)

tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly
  • -d( --declaration): สร้าง*.d.tsไฟล์
  • --declarationDir dist/lib: ไดเร็กทอรีเอาต์พุตสำหรับไฟล์การประกาศที่สร้างขึ้น
  • --declarationMap: สร้าง sourcemap สำหรับไฟล์ '.d.ts' ที่เกี่ยวข้องแต่ละไฟล์
  • --emitDeclarationOnly: ปล่อยเฉพาะไฟล์การประกาศ '.d.ts' (ไม่มี JS รวบรวม)

(ดูเอกสารสำหรับตัวเลือกคอมไพเลอร์บรรทัดคำสั่งทั้งหมด)

หรือตัวอย่างในpackage.json:

"scripts": {
    "build:types": "tsc -d --declarationDir dist/lib --declarationMap --emitDeclarationOnly",
}

จากนั้นเรียกใช้: yarn build:types(หรือnpm run build:types)


ฉันยังไม่สามารถหาวิธีสร้างd.tsไฟล์และใช้อินเตอร์เฟสได้ คุณมีตัวอย่างหรือไม่?
Danosaure

สคริปต์ npm ด้านบนจะสร้าง*.d.tsไฟล์และวางไว้ในdist/libโฟลเดอร์ คุณต้องการtsconfig.jsonไฟล์ในรูทของโปรเจ็กต์ของคุณ แต่มันควรจะอยู่ที่นั่นเพื่อให้โปรเจคทำงานได้
magikMaker

ฉันไม่สามารถใช้งานได้เมื่อถูกเปิดเผย ฉันมีโพสต์ต่อไปนี้stackoverflow.com/questions/59742688หากคุณสามารถใช้งานได้
Danosaure
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.