টাইপস্ক্রিপ্ট 2: টাইপযুক্ত এনপিএম মডিউলটির জন্য কাস্টম টাইপগুলি


93

অন্যান্য জায়গায় পোস্ট পরামর্শের চেষ্টা করার পরে , আমি নিজেকে টাইপ স্ক্রিপ্ট প্রজেক্টটি চালাতে অক্ষম বলে মনে করি যাতে একটি টাইপযুক্ত এনপিএম মডিউল ব্যবহার করা হয়। নীচে একটি সর্বনিম্ন উদাহরণ এবং আমি যে পদক্ষেপগুলি চেষ্টা করেছি তা নীচে

এই সর্বনিম্ন উদাহরণের জন্য, আমরা ভান করব যেগুলির lodashবিদ্যমান ধরণের সংজ্ঞা নেই। এর মতো, আমরা প্যাকেজটিকে উপেক্ষা করব @types/lodashএবং ম্যানুয়ালি এটির টাইপিং ফাইলগুলি lodash.d.tsআমাদের প্রকল্পে যুক্ত করার চেষ্টা করব ।

ফোল্ডার কাঠামো

  • নোড_মডিউলস
    • লোডাশ
  • src
    • foo.ts
  • টাইপিং
    • প্রথা
      • lodash.d.ts
    • গ্লোবাল
    • index.d.ts
  • package.json
  • tsconfig.json
  • typings.json

এরপরে, ফাইলগুলি।

ফাইল foo.ts

///<reference path="../typings/custom/lodash.d.ts" />
import * as lodash from 'lodash';

console.log('Weeee');

ফাইলটি lodash.d.tsসরাসরি @types/lodashপ্যাকেজ থেকে অনুলিপি করা হয় ।

ফাইল index.d.ts

/// <reference path="custom/lodash.d.ts" />
/// <reference path="globals/lodash/index.d.ts" />

ফাইল package.json

{
  "name": "ts",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "typings": "./typings/index.d.ts",
  "dependencies": {
    "lodash": "^4.16.4"
  },
  "author": "",
  "license": "ISC"
}

ফাইল tsconfig.json

{
  "compilerOptions": {
    "target": "ES6",
    "jsx": "react",
    "module": "commonjs",
    "sourceMap": true,
    "noImplicitAny": true,
    "experimentalDecorators": true,
    "typeRoots" : ["./typings"],
    "types": ["lodash"]
  },
  "include": [
    "typings/**/*",
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"
  ]
}

ফাইল typings.json

{
    "name": "TestName",
    "version": false,
    "globalDependencies": {
        "lodash": "file:typings/custom/lodash.d.ts"
    }
}

আপনি দেখতে পাচ্ছেন, আমি টাইপগুলি আমদানির বিভিন্ন উপায় চেষ্টা করেছি:

  1. এটি সরাসরি আমদানি করে foo.ts
  2. একটি typingsসম্পত্তি দ্বারাpackage.json
  3. ব্যবহারের typeRootsমধ্যে tsconfig.jsonএকটি ফাইলের সাথেtypings/index.d.ts
  4. একটি সুনির্দিষ্ট ব্যবহারের typesমধ্যেtsconfig.json
  5. typesডিরেক্টরিটি অন্তর্ভুক্ত করেtsconfig.json
  6. একটি কাস্টম typings.jsonফাইল তৈরি করে এবং চলমানtypings install

তবুও, আমি টাইপস্ক্রিপ্ট চালানোর সময়:

E:\temp\ts>tsc
error TS2688: Cannot find type definition file for 'lodash'.

আমি কি ভুল করছি?

উত্তর:


210

দুর্ভাগ্যক্রমে এই জিনিসগুলি বর্তমানে খুব ভালভাবে নথিভুক্ত করা হয়নি, তবে আপনি এটির কাজটি করতে সক্ষম হলেও, আসুন আপনার কনফিগারেশনটি এগিয়ে চলুন যাতে আপনি বুঝতে পারবেন যে প্রতিটি অংশ কী করছে এবং এটি কীভাবে টাইপস্ক্রিপ্ট প্রক্রিয়া এবং টাইপগুলি বোঝায় তার সাথে সম্পর্কিত।

প্রথমে আপনি যে ত্রুটিটি পাচ্ছেন তার উপর নজর দেওয়া যাক:

error TS2688: Cannot find type definition file for 'lodash'.

এই ত্রুটিটি আসলে আপনার আমদানি বা রেফারেন্সগুলি থেকে আসে না বা আপনার টিএস ফাইলে যে কোনও জায়গায় লোডাশ ব্যবহার করার চেষ্টা করে। বরং এটি কীভাবে সম্পত্তি typeRootsএবং typesবৈশিষ্ট্যগুলি ব্যবহার করবেন সে সম্পর্কে একটি ভুল বোঝাবুঝি থেকে আসে , সুতরাং আসুন সেগুলির বিষয়ে আরও কিছু বিশদে যাওয়া যাক।

সম্পর্কে জিনিস typeRoots:[]এবং types:[]বৈশিষ্ট্য যে তারা হয় না সাধারণ উপায়ে নির্বিচারে ঘোষণা (লোড করতে *.d.ts) ফাইল।

এই দুটি বৈশিষ্ট্য সরাসরি নতুন টিএস 2.0 বৈশিষ্ট্যের সাথে সম্পর্কিত যা এনপিএম প্যাকেজগুলি থেকে প্যাকেজিং এবং লোড টাইপিং ঘোষণার মঞ্জুরি দেয় ।

এটি বোঝার জন্য অত্যন্ত গুরুত্বপূর্ণ যে এগুলি কেবলমাত্র এনপিএম ফর্ম্যাটে ফোল্ডারগুলির সাথে কাজ করে (যেমন একটি ফোল্ডার যা একটি প্যাকেজ.জসন বা index.d.ts রয়েছে )।

এর জন্য ডিফল্ট typeRootsহ'ল:

{
   "typeRoots" : ["node_modules/@types"]
}

ডিফল্টরূপে এর অর্থ হ'ল টাইপস্ক্রিপ্ট node_modules/@typesফোল্ডারে যাবে এবং এটি এনপিএম প্যাকেজ হিসাবে খুঁজে পাওয়া প্রতিটি উপ-ফোল্ডার লোড করার চেষ্টা করবে ।

এটি বুঝতে গুরুত্বপূর্ণ যে কোনও ফোল্ডারে এনপিএম প্যাকেজের মতো কাঠামো না থাকলে এটি ব্যর্থ হবে।

আপনার ক্ষেত্রে এটি ঘটছে এবং এটি আপনার প্রাথমিক ত্রুটির উত্স।

আপনি টাইপ রুট হতে সুইচ করেছেন:

{
    "typeRoots" : ["./typings"]
}

এর অর্থ হ'ল টাইপস্ক্রিপ্ট এখন সাবফোল্ডারগুলির./typings জন্য ফোল্ডারটি স্ক্যান করবে এবং এটি এনপিএম মডিউল হিসাবে পাওয়া প্রতিটি সাবফোল্ডার লোড করার চেষ্টা করবে।

সুতরাং আসুন আপনি ভেবে দেখান যে আপনি ঠিক আছে typeRootsসেটআপ করার জন্য নির্দেশিত ./typingsকিন্তু এখনও কোন types:[]সম্পত্তি সেটআপ আছে। আপনি সম্ভবত এই ত্রুটিগুলি দেখতে পাবেন:

error TS2688: Cannot find type definition file for 'custom'.
error TS2688: Cannot find type definition file for 'global'.

এটি কারণ tscআপনার ./typingsফোল্ডারটি স্ক্যান করছে এবং উপ-ফোল্ডারগুলি সন্ধান করছে customএবং global। এরপরে এটি এনপিএম প্যাকেজ-টাইপ টাইপিং হিসাবে ব্যাখ্যা করার চেষ্টা করা হচ্ছে, তবে এই ফোল্ডারগুলিতে কোনও index.d.tsবা নেই package.jsonএবং তাই আপনি ত্রুটি পান।

এখন types: ['lodash']আপনি যে সম্পত্তিটি সেট করছেন সে সম্পর্কে কিছুটা কথা বলা যাক । এটি কি করে? ডিফল্টরূপে, টাইপস্ক্রিপ্ট এটি আপনার মধ্যে পাওয়া সমস্ত সাব-ফোল্ডার লোড করবে typeRoots। আপনি যদি কোনও types:সম্পত্তি নির্দিষ্ট করেন তবে এটি কেবলমাত্র সেই নির্দিষ্ট সাব-ফোল্ডারগুলি লোড করবে।

আপনার ক্ষেত্রে আপনি এটি ./typings/lodashফোল্ডারটি লোড করতে বলছেন তবে এটি বিদ্যমান নেই। এই কারণেই আপনি পান:

error TS2688: Cannot find type definition file for 'lodash'

সুতরাং আসুন আমরা কি শিখেছি সংক্ষেপে। টাইপস্ক্রিপ্ট ২.০ প্রবর্তিত হয়েছে typeRootsএবং এনপিএম প্যাকেজেtypes প্যাকেজড ডিক্লেয়ারেশন ফাইলগুলি লোড করার জন্য । আপনার যদি কাস্টম টাইপিং বা একক আলগা ফাইল রয়েছে যা এনপিএম প্যাকেজ কনভেনশন অনুসরণ করে কোনও ফোল্ডারে অন্তর্ভুক্ত নেই, তবে এই দুটি নতুন বৈশিষ্ট্য আপনি ব্যবহার করতে চান তা নয়। টাইপসক্রিপ্ট ২.০ আসলে কীভাবে এটি ব্যবহার করা হবে তা পরিবর্তন করে না। আপনাকে কেবলমাত্র অনেকগুলি মানক উপায়ের মধ্যে এই সংকলন প্রসঙ্গে এই ফাইলগুলি অন্তর্ভুক্ত করতে হবে:d.ts

  1. এটি সরাসরি কোনও .tsফাইলে অন্তর্ভুক্ত করুন: ///<reference path="../typings/custom/lodash.d.ts" />

  2. ./typings/custom/lodash.d.tsআপনার files: []সম্পত্তি সহ ।

  3. সহ ./typings/index.d.tsআপনার files: []সম্পত্তি (যা পরে যাও recursively অন্যান্য typings অন্তর্ভুক্ত করা হয়েছে।

  4. ./typings/**আপনার যুক্ত করা হচ্ছেincludes:

আশা করি, এই আলোচনার ভিত্তিতে আপনি বলতে পারবেন যে আপনি নিজের tsconfig.jsonতৈরি জিনিসগুলিতে পাগল হওয়া পরিবর্তনগুলি কেন আবার কাজ করে।

সম্পাদনা:

একটি জিনিস যা আমি উল্লেখ করতে ভুলে গেছি তা হ'ল typeRootsএবং typesসম্পত্তি বিশ্বব্যাপী ঘোষণাগুলি স্বয়ংক্রিয়ভাবে লোড করার জন্য কেবল কার্যকর ।

উদাহরণস্বরূপ যদি আপনি

npm install @types/jquery

এবং আপনি ডিফল্ট tsconfig ব্যবহার করছেন, তারপরে সেই jquery প্রকারের প্যাকেজটি স্বয়ংক্রিয়ভাবে লোড হবে এবং $আপনার সমস্ত স্ক্রিপ্টগুলিতে উপলব্ধ হবে যে আরও কিছু করতে হবে না ///<reference/>বাimport

typeRoots:[]সম্পত্তি যেখানে টাইপ থেকে অতিরিক্ত অবস্থান জুড়তে বোঝানো হয় প্যাকেজ স্বয়ংক্রিয়ভাবে frrom লোড হবে।

types:[]সম্পত্তি প্রাথমিক ব্যবহার-কেস স্বয়ংক্রিয় লোড আচরণ নিষ্ক্রিয় করতে (একটি খালি অ্যারে থেকে এটি সেটিং দ্বারা) হল, এবং তারপর শুধুমাত্র আপনি বিশ্বব্যাপী অন্তর্ভুক্ত করতে চান নির্দিষ্ট ধরনের তালিকা।

বিভিন্ন থেকে টাইপ প্যাকেজ লোড করার অন্য উপায়টি typeRootsহ'ল নতুন ///<reference types="jquery" />নির্দেশিকা ব্যবহার করা । typesপরিবর্তে লক্ষ্য করুন path। আবার, এটি কেবল গ্লোবাল ডিক্লেয়ারেশন ফাইলগুলির জন্য দরকারী, সাধারণত যেগুলি না করে import/export

এখন, এখানে এমন একটি জিনিস যা বিভ্রান্তির কারণ হয় typeRoots। মনে রাখবেন, আমি বলেছিলাম যে typeRootsএটি মডিউলগুলির বিশ্বব্যাপী অন্তর্ভুক্তি সম্পর্কে। তবে @types/folderস্ট্যান্ডার্ড মডিউল-রেজোলিউশনেও জড়িত (আপনার typeRootsসেটিং নির্বিশেষে )।

বিশেষ করে, স্পষ্টভাবে আমদানি মডিউল সবসময় সব রোধ করা যাবে includes, excludes, files, typeRootsএবং typesঅপশন। সুতরাং আপনি যখন করবেন:

import {MyType} from 'my-module';

উল্লিখিত সমস্ত বৈশিষ্ট্য সম্পূর্ণ উপেক্ষা করা হয়। চলাকালীন এর সাথে প্রাসঙ্গিক বৈশিষ্ট্য মডিউল রেজল্যুশন আছে baseUrl, pathsএবং moduleResolution

মূলত, যখন ব্যবহার nodeমডিউল রেজল্যুশন, এটা অনুসন্ধানের একটি ফাইল নামের জন্য শুরু হবে my-module.ts, my-module.tsx, my-module.d.tsফোল্ডারের থেকে শুরু আপনার দ্বারা প্রতি ইঙ্গিত baseUrlকনফিগারেশন।

এটা ফাইল খুঁজে না ফেলেন, তাহলে এটি নামে একটি ফোল্ডার জন্য চেহারা হবে my-moduleএবং তারপর একটি অনুসন্ধান package.jsonএকটি সঙ্গে typingsসম্পত্তি, আছে যদি package.jsonবা কোন typingsএটি কহন ভিতরে সম্পত্তি যা ফাইল লোড করতে তাহলে অনুসন্ধান করবে index.ts/tsx/d.tsযে ফোল্ডারে মধ্যে।

যদি এটি এখনও সফল না হয় তবে এটি node_modulesআপনার থেকে শুরু হওয়া ফোল্ডারে এই একই জিনিসগুলি অনুসন্ধান করবে baseUrl/node_modules

তদ্ব্যতীত, যদি এটি এগুলি না পায় তবে এটি baseUrl/node_modules/@typesএকই জিনিসগুলির জন্য অনুসন্ধান করবে ।

যদি এটি এখনও কিছু না পেয়ে থাকে তবে এটি পিতামাতার ডিরেক্টরিতে node_modulesএবং node_modules/@typesসেখানে অনুসন্ধান শুরু করবে । এটি আপনার ফাইল সিস্টেমের মূল পর্যন্ত পৌঁছে না দেওয়া পর্যন্ত ডিরেক্টরিগুলি চালিয়ে যেতে থাকবে (এমনকি আপনার প্রকল্পের বাইরে নোড-মডিউল পেতেও)।

একটা জিনিস আমি জোর দিতে চাই তা হল মডিউল রেজোলিউশন typeRootsআপনার সেট করা যে কোনওটিকে পুরোপুরি উপেক্ষা করে । সুতরাং আপনি যদি কনফিগার typeRoots: ["./my-types"]করেন তবে সুস্পষ্ট মডিউল রেজোলিউশনের সময় এটি অনুসন্ধান করা হবে না। এটি কেবলমাত্র একটি ফোল্ডার হিসাবে কাজ করে যেখানে আপনি বিশ্বব্যাপী সংজ্ঞা ফাইলগুলি রাখতে পারেন যা আপনি পুরো অ্যাপ্লিকেশনটিতে আমদানি বা রেফারেন্সের প্রয়োজন ছাড়াই উপলব্ধ করতে চান।

শেষ অবধি, আপনি প্যাথ ম্যাপিংস (অর্থাত্ pathsসম্পত্তি) এর সাথে মডিউল আচরণটি ওভাররাইড করতে পারেন । সুতরাং উদাহরণস্বরূপ, আমি উল্লেখ করেছি যে typeRootsমডিউলটি সমাধান করার চেষ্টা করার সময় কোনও কাস্টমসের সাথে পরামর্শ করা হয় না। তবে আপনি যদি পছন্দ করেন তবে আপনি এই আচরণটি ঘটতে পারেন:

"paths" :{
     "*": ["my-custom-types/*", "*"]
 }

এটি যা করে সেই সমস্ত আমদানির জন্য যা বাম-হাতের সাথে মিলে যায়, আমদানিটি অন্তর্ভুক্ত করার চেষ্টা করার আগে ডানদিকের মতো পরিবর্তন করার চেষ্টা *করুন ( ডানদিকে থাকাটি আপনার প্রাথমিক আমদানি স্ট্রিংকে উপস্থাপন করে example উদাহরণস্বরূপ যদি আপনি আমদানি করেন:

import {MyType} from 'my-types';

এটি প্রথমে আমদানির চেষ্টা করবে যেমন আপনি লিখেছেন:

import {MyType} from 'my-custom-types/my-types'

এবং তারপরে এটি যদি না খুঁজে পাওয়া যায় তবে উপসর্গটি ছাড়াই আবার চেষ্টা করবে (অ্যারের দ্বিতীয় আইটেমটি *যার অর্থ প্রাথমিক আমদানি।

সুতরাং আপনি কাস্টম ডিক্লেয়ারেশন ফাইলগুলি বা এমনকি .tsআপনি যে কাস্টম মডিউলগুলি সক্ষম করতে চান তা অনুসন্ধান করতে অতিরিক্ত ফোল্ডার যুক্ত করতে পারেন import

আপনি নির্দিষ্ট মডিউলগুলির জন্য কাস্টম ম্যাপিংগুলিও তৈরি করতে পারেন:

"paths" :{
   "*": ["my-types", "some/custom/folder/location/my-awesome-types-file"]
 }

এটি আপনাকে করতে দেয়

import {MyType} from 'my-types';

তবে তারপরে এই ধরণের পড়ুন some/custom/folder/location/my-awesome-types-file.d.ts


4
আপনার বিস্তারিত উত্তরের জন্য ধন্যবাদ। এটি সমাধানগুলিকে বিচ্ছিন্নকরণে কাজ করে তবে তারা ভালভাবে মিশে না। এটি জিনিসগুলি স্পষ্ট করে তাই আমি আপনাকে অনুগ্রহ দেব। আপনি যদি আরও কয়েকটি পয়েন্টের উত্তর দেওয়ার জন্য সময়টি খুঁজে পেতে পারেন তবে এটি অন্য ব্যক্তির পক্ষে সত্যই সহায়ক হতে পারে। (1) টাইপরুটগুলির জন্য কেবল কোনও নির্দিষ্ট ফোল্ডার কাঠামো গ্রহণ করার কোনও কারণ আছে? মনে হয় নির্বিচারে। (২) যদি আমি টাইপরুটগুলি পরিবর্তন করি তবে টাইপসক্রিপ্টটিতে নোট_মডিউলগুলিতে @ টাইপ ফোল্ডারগুলি অন্তর্ভুক্ত রয়েছে, যা অনুমানের বিপরীতে রয়েছে। (৩) টাইপিংয়ের উদ্দেশ্যে কী pathsএবং কীভাবে এটি আলাদা include?
Jodiug

4
আমি উত্তরটি সম্পাদনা করেছি, আপনার যদি আরও কোনও প্রশ্ন থাকে তবে আমাকে জানান।
dtabuenc

4
আপনাকে ধন্যবাদ, আমি বাকি এবং বাহ পড়ি। এই সমস্ত সন্ধানের জন্য আপনাকে প্রপস। দেখে মনে হচ্ছে এখানে কাজের জায়গায় অহেতুক জটিল আচরণ অনেক বেশি। আমি আশা করি টাইপস্ক্রিপ্ট ভবিষ্যতে তাদের কনফিগার বৈশিষ্ট্যগুলিকে আরও কিছুটা স্ব-ডকুমেন্টিং করে তুলবে।
Jodiug

4
সেখান থেকে এই উত্তর একটি লিঙ্ক হওয়া উচিত typescriptlang.org/docs/handbook/tsconfig-json.html
hgoebl

4
শেষ উদাহরণটির মতো হওয়া উচিত নয় "paths" :{ "my-types": ["some/custom/folder/location/my-awesome-types-file"] }?
কোয়েন

6

সম্পাদনা: পুরানো। উপরে উত্তর পড়ুন।

আমি এখনও এটি বুঝতে পারি না, তবে আমি একটি সমাধান পেয়েছি। নিম্নলিখিত ব্যবহার করুন tsconfig.json:

{
  "compilerOptions": {
    "target": "ES6",
    "jsx": "react",
    "module": "commonjs",
    "sourceMap": true,
    "noImplicitAny": true,
    "experimentalDecorators": true,
    "baseUrl": ".",
    "paths": {
      "*": [
        "./typings/*"
      ]
    }
  },
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "**/*.spec.ts"
  ]
}

সরান typings.jsonএবং ফোল্ডার অধীনে সবকিছু typingsব্যতীত lodash.d.ts। এছাড়াও সমস্ত ///...উল্লেখ মুছে ফেলুন


3

"*": ["./types/*"] Tsconfig পথে এই লাইনটি 2 ঘন্টা সংগ্রামের পরে সবকিছু স্থির করে।

{
  "compilerOptions": {
    "moduleResolution": "node",
    "strict": true,
    "baseUrl": ".",
    "paths": {
      "*": ["./types/*"]
    },
    "jsx": "react",
    "types": ["node", "jest"]
  },
  "include": [
    "client/**/*",
    "packages/**/*"
  ],
  "exclude": [
    "node_modules/**/*"
  ]
}

ধরনের ফোল্ডার নাম, যার মধ্যে স্তরের node_module অর্থাত পাশে বসে নেই ক্লায়েন্ট ফোল্ডারে (অথবা src ফোল্ডার) types/third-party-lib/index.d.ts
index.d.ts হয়েছেdeclare module 'third-party-lib';

দ্রষ্টব্য: উপরের কনফিগারেশনটি একটি অসম্পূর্ণ কনফিগারেশন, এটির মধ্যে কীভাবে প্রকার, পথ, অন্তর্ভুক্ত এবং বাদ দিয়ে দেওয়া হয় তার ধারণা দেওয়ার জন্য।


2

আমি জানি এটি একটি পুরানো প্রশ্ন, তবে টাইপস্ক্রিপ্ট টুলিং অবিচ্ছিন্নভাবে পরিবর্তিত হচ্ছে। আমি মনে করি এই মুহুর্তে সর্বোত্তম বিকল্পটি কেবল tsconfig.json এ "অন্তর্ভুক্ত" পাথের সেটিংসের উপর নির্ভর করবে।

  "include": [
        "src/**/*"
    ],

ডিফল্টরূপে, আপনি যদি নির্দিষ্ট পরিবর্তন না করেন তবে সমস্ত * .ts এবং সমস্ত * .d.ts ফাইলগুলি src/স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত হবে। আমি মনে করি এটা সবচেয়ে সহজ পদ্ধিতি হল / সবচেয়ে ভালো উপায় কাস্টমাইজ ছাড়া কাস্টম টাইপ ঘোষণা ফাইল অন্তর্ভুক্ত হয় typeRootsএবং types

তথ্যসূত্র:

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.