เกี่ยวกับ“ * .d.ts” ใน TypeScript


343

ฉันรู้สึกอยากรู้อยากเห็น*.d.tsเพราะฉันเป็นมือใหม่ใน TypeScript และมีคนบอกฉันว่าไฟล์ประเภทนี้คล้ายกับ "head file" ใน C ++ แต่สำหรับ JS เท่านั้น แต่ผมไม่สามารถแปลงไฟล์ JS บริสุทธิ์เพื่อ*.d.tsไฟล์จนกว่าฉัน forcely เปลี่ยนไป*.js *.tsดังนั้นฉันมีสามไฟล์: ไฟล์ JS, ไฟล์ TS และ*.d.tsไฟล์


  1. ความสัมพันธ์ระหว่างพวกเขาคืออะไร?

  2. ฉันจะใช้*.d.tsไฟล์ได้อย่างไร หมายความว่าฉันสามารถลบ*.tsไฟล์อย่างถาวรได้หรือไม่

  3. ถ้าเป็นเช่นนั้น*.d.tsไฟล์จะรู้ได้อย่างไรว่าไฟล์ JS ใดทำการแมปกับตัวเอง?


มันคงจะดีมากถ้ามีคนยกตัวอย่างให้ฉัน


สำหรับคนในอนาคต: ดูเอกสารของ TypeScript: typescriptlang.org/docs/handbook/declaration-files/templates/…
J.Ko

คำตอบ:


349

ไฟล์ "d.ts" ใช้เพื่อจัดเตรียมข้อมูลประเภทตัวพิมพ์เกี่ยวกับ API ที่เขียนใน JavaScript แนวคิดคือคุณกำลังใช้บางอย่างเช่น jQuery หรือขีดล่างซึ่งเป็นไลบรารีจาวาสคริปต์ที่มีอยู่ คุณต้องการที่จะบริโภคเหล่านั้นจากรหัส typescript ของคุณ

แทนที่จะเขียน jquery หรือขีดล่างหรืออะไรก็ตามใน typescript คุณสามารถเขียนไฟล์ d.ts แทนซึ่งมีเฉพาะคำอธิบายประกอบประเภท จากรหัส typescript ของคุณคุณจะได้รับประโยชน์ typescript ของการตรวจสอบชนิดคงที่ในขณะที่ยังใช้ไลบรารี JS บริสุทธิ์


26
ขอบคุณมาก! แต่จะแม็พไฟล์ * .d.ts กับไฟล์ js ได้อย่างไร ไฟล์ js รู้ได้อย่างไรว่าไฟล์ d.ts ใดมีการจับคู่กับตัวเอง คุณยกตัวอย่างให้ฉันได้ไหม

3
แต่ไฟล์ d.ts สร้างขึ้นจากไฟล์ js และหากไฟล์ js ไม่รู้อะไรเกี่ยวกับ d.ts วิธีการเรียกใช้ฟังก์ชั่นจาก d.ts ในไฟล์ ts อื่น ๆ ที่ไม่มีไฟล์ js? ฉันงงงัน ......

8
ดูstackoverflow.com/questions/18091724/... คุณต้องเพิ่ม /// <บรรทัดอ้างอิงที่ด้านบนของไฟล์ทีเอสที่ใช้งาน คุณจะต้องมีทั้งไฟล์ d.ts และ. js
Chris Tavares

3
โดยทั่วไปไฟล์ d.ts จะเขียนด้วยลายมือจากเอกสาร js จำนวนมากเหล่านี้สามารถใช้ได้สำหรับห้องสมุดจาวาสคริปต์ที่เป็นที่นิยม: github.com/borisyankov/DefinitelyTyped
basarat

12
คุณวางไฟล์ d.ts ที่กำหนดเองไว้ที่ไหนถ้าคุณสร้างไฟล์ที่กำหนดเองสำหรับโครงการของคุณ
Jay

77

dย่อมาจากไฟล์ Declaration :

เมื่อสคริปต์ TypeScript ได้รับการรวบรวมจะมีตัวเลือกในการสร้างไฟล์ประกาศ (ที่มีนามสกุล. d.ts) ซึ่งทำหน้าที่เป็นอินเทอร์เฟซสำหรับส่วนประกอบใน JavaScript ที่รวบรวม ในกระบวนการคอมไพเลอร์จะตัดส่วนฟังก์ชันและเมธอดทั้งหมดออกและเก็บรักษาเฉพาะลายเซ็นต์ของชนิดที่ถูกเอ็กซ์พอร์ต ไฟล์ประกาศผลที่ได้นั้นสามารถใช้เพื่ออธิบายประเภท TypeScript เสมือนที่ส่งออกของไลบรารี JavaScript หรือโมดูลเมื่อนักพัฒนาบุคคลที่สามใช้งานจาก TypeScript

แนวคิดของไฟล์การประกาศคล้ายกับแนวคิดของไฟล์ส่วนหัวที่พบใน C / C ++

declare module arithmetics {
    add(left: number, right: number): number;
    subtract(left: number, right: number): number;
    multiply(left: number, right: number): number;
    divide(left: number, right: number): number;
}

ไฟล์การประกาศชนิดสามารถเขียนด้วยมือสำหรับไลบรารี JavaScript ที่มีอยู่ได้เช่นเดียวกับ jQuery และ Node.js

คอลเลกชันขนาดใหญ่ของไฟล์ที่ประกาศสำหรับห้องสมุด JavaScript นิยมเป็นโฮสต์บน GitHub ในDefinitelyTypedและtypings Registry ยูทิลิตีบรรทัดคำสั่งที่เรียกว่าtypingsมีไว้เพื่อช่วยค้นหาและติดตั้งไฟล์ประกาศจากแหล่งเก็บข้อมูล


3
หมายเหตุ: typingsเครื่องมือบรรทัดคำสั่งไม่จำเป็นจริงๆตั้งแต่ TypeScript 2.0 วิธีการที่เป็นปัจจุบันมากขึ้นคือการใช้ wrappers การพิมพ์ผ่านที่เก็บ npm ภายใต้@typesnamespace สำหรับรายละเอียดเพิ่มเติมโปรดดูgithub.com/typings/typings/blob/master/README.md
Burt_Harris

1
@takeshin ฉันมีคำถาม ฉันจำเป็นต้องสร้างไฟล์. d.ts ของไฟล์. tsx ที่ใช้ภายในโครงการของฉันหรือไม่ สิ่งเหล่านี้กำลังเพิ่มสิ่งอื่นนอกเหนือจากการให้ความเป็นไปได้กับห้องสมุดบุคคลที่สามหรือไม่?
Krzysztof Trzos

63

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

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

เช่น: test.jsและtest.d.tsอยู่ในtestdir/โฟลเดอร์จากนั้นคุณนำเข้ามันเช่นนี้ในองค์ประกอบการตอบสนอง:

import * as Test from "./testdir/test";

.d.tsไฟล์ได้รับการส่งออกเป็น namespace เช่นนี้:

export as namespace Test;

export interface TestInterface1{}
export class TestClass1{}

42
ไม่มีใครให้คำตอบเกี่ยวกับวิธีเชื่อมต่อ d.ts กับ js ดังนั้นฉันคิดว่านี่เป็นสถานที่ที่เหมาะสม
ConstantinM

โปรดทราบว่าหากคุณกำลังสร้างไฟล์การประกาศสำหรับ JS บางตัวที่คุณไม่ได้สร้าง (ตัวอย่างจากแพคเกจ npm) ว่า.d.tsไฟล์นั้นจะต้องตั้งชื่อเช่นเดียวกับแพคเกจที่จะนำเข้า
electrovir

31

ตัวอย่างการทำงานสำหรับกรณีเฉพาะ :

สมมติว่าคุณมีโมดูลของฉันที่คุณกำลังใช้งานร่วมกันผ่านทางNPM

คุณติดตั้งมันด้วย npm install my-module

คุณใช้มัน:

import * as lol from 'my-module';

const a = lol('abc', 'def');

ตรรกะของโมดูลทั้งหมดอยู่ในindex.js:

module.exports = function(firstString, secondString) {

  // your code

  return result
}

หากต้องการเพิ่มการพิมพ์ให้สร้างไฟล์index.d.ts:

declare module 'my-module' {
  export default function anyName(arg1: string, arg2: string): MyResponse;
}

interface MyResponse {
  something: number;
  anything: number;
}

19

Like @takeshin กล่าวว่า. d หมายถึงไฟล์ประกาศสำหรับ typescript (.ts)

คะแนนน้อยที่จะชี้แจงก่อนดำเนินการต่อเพื่อตอบโพสต์นี้ -

  1. typescript เป็น superset ทางไวยากรณ์ของ javascript
  2. typescript ไม่ทำงานด้วยตัวเอง แต่จะต้องแปลงเป็น javascript ( typescript เพื่อการแปลง javascript )
  3. "การกำหนดประเภท" และ "การตรวจสอบประเภท" เป็นฟังก์ชั่นเสริมที่ typescript จัดเตรียมไว้ให้มากกว่าจาวาสคริปต์ ( ตรวจสอบความแตกต่างระหว่างสคริปต์ประเภทและจาวาสคริปต์ )

หากคุณกำลังคิดว่า typescript เป็นเพียง syntactic superset มันให้ประโยชน์อะไรบ้าง - https://basarat.gitbooks.io/typescript/docs/why-typescript.html#the-typescript-type-system

เพื่อตอบกระทู้นี้ -

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

สำหรับอดีต -

หากคุณติดตั้งไลบรารี javascript -

npm install --save mylib

และลองนำเข้ามันในรหัส typescript -

import * from "mylib";

คุณจะได้รับข้อผิดพลาด

"ไม่พบโมดูล" mylib "

ดังที่ @Chris ห้องสมุดหลายแห่งเช่นเครื่องหมายขีดล่าง Jquery ถูกเขียนด้วย javascript แล้ว แทนที่จะเขียนไลบรารีเหล่านั้นใหม่สำหรับโปรเจ็กต์ typescript ต้องการโซลูชันทางเลือก

ในการทำเช่นนี้คุณสามารถให้ไฟล์ประกาศประเภทในไลบรารี javascript ชื่อ * .d.ts เช่นในกรณีข้างต้น mylib.d.ts ไฟล์การประกาศให้การประกาศประเภทของฟังก์ชันและตัวแปรที่กำหนดในไฟล์จาวาสคริปต์ที่เกี่ยวข้องเท่านั้น

ตอนนี้เมื่อคุณลอง -

import * from "mylib";

mylib.d.ts ได้รับการนำเข้าซึ่งทำหน้าที่เป็นส่วนต่อประสานระหว่างโค้ดไลบรารี javascript และโปรเจ็กต์ typescript


3

คำตอบนี้จะถือว่าคุณมี JavaScript บางอย่างที่คุณไม่ต้องการที่จะแปลง typescript .jsแต่คุณต้องการที่จะได้รับประโยชน์จากการตรวจสอบชนิดที่มีการเปลี่ยนแปลงน้อยที่สุดเพื่อคุณ .d.tsไฟล์มากเช่น C หรือไฟล์ส่วนหัว C ++ โดยมีวัตถุประสงค์คือเพื่อกำหนดอินเตอร์เฟซ นี่คือตัวอย่าง:

mashString.d.ts

/** Makes a string harder to read. */
declare function mashString(
    /** The string to obscure */
    str: string
):string;
export = mashString;

mashString.js

// @ts-check
/** @type {import("./mashString")} */
module.exports = (str) => [...str].reverse().join("");

main.js

// @ts-check
const mashString = require("./mashString");
console.log(mashString("12345"));

ความสัมพันธ์ที่นี่คือ: mashString.d.tsกำหนดอินเทอร์เฟซmashString.jsใช้อินเทอร์เฟซและmain.jsใช้อินเทอร์เฟซ

ในการรับการตรวจสอบประเภทเพื่อใช้งานคุณเพิ่มลง// @ts-check ใน.jsไฟล์ของคุณ แต่นี่เป็นการตรวจสอบเท่านั้นที่main.jsใช้อินเทอร์เฟซอย่างถูกต้อง เพื่อให้แน่ใจว่าmashString.jsดำเนินการอย่างถูกต้องเราเพิ่ม/** @type {import("./mashString")} */ก่อนการส่งออก

คุณสามารถสร้าง.d.tsไฟล์เริ่มต้นโดยใช้tsc -allowJs main.js -dจากนั้นแก้ไขตามต้องการด้วยตนเองเพื่อปรับปรุงการตรวจสอบประเภทและเอกสาร

mashStringในกรณีส่วนใหญ่การดำเนินการและอินเตอร์เฟซที่มีชื่อเดียวกันที่นี่ แต่คุณสามารถมีการใช้งานทางเลือก ยกตัวอย่างเช่นเราสามารถเปลี่ยนชื่อmashString.jsไปและมีทางเลือกreverse.jsencryptString.js

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.