typescript - Nebolo možné nájsť deklaráciu súboru pre modul 'module-name'. '/path/to/module-name.js' má implicitne typ 'any'
Čítal som, ako funguje riešenie modulov v TypeScripte.
Mám nasledujúce úložisko: @ts-stack/di. Po kompilácii je štruktúra adresárov nasledovná:
├── dist
│ ├── annotations.d.ts
│ ├── annotations.js
│ ├── index.d.ts
│ ├── index.js
│ ├── injector.d.ts
│ ├── injector.js
│ ├── profiler.d.ts
│ ├── profiler.js
│ ├── providers.d.ts
│ ├── providers.js
│ ├── util.d.ts
│ └── util.js
├── LICENSE
├── package.json
├── README.md
├── src
│ ├── annotations.ts
│ ├── index.ts
│ ├── injector.ts
│ ├── profiler.ts
│ ├── providers.ts
│ └── util.ts
└── tsconfig.json
V mojom súbore package.json som napísal "main": "dist/index.js".
V Node.js všetko funguje dobre, ale TypeScript:
import {Injector} from '@ts-stack/di';
Nedalo sa nájsť súbor deklarácie pre modul '@ts-stack/di'. '/path/to/node_modules/@ts-stack/di/dist/index.js' má implicitný typ 'any'.
A predsa, ak importujem nasledovne, všetko funguje:
import {Injector} from '/path/to/node_modules/@ts-stack/di/dist/index.js';
Čo robím zle?
Odpoveď č. 1
Tu je iné riešenie
Keď modul nie je váš - skúste nainštalovať typy z @types:
npm install -D @types/module-name
Odpoveď č. 2
Ak importujete modul tretej strany 'foo', ktorý neposkytuje žiadne typy, ani v samotnej knižnici, ani v balíku @types/foo (vygenerovanom z repozitára DefinitelyTyped), môžete túto chybu odstrániť deklarovaním modulu v súbore s príponou .d.ts. TypeScript hľadá súbory .d.ts na rovnakých miestach, kde hľadá bežné súbory .ts: podľa toho, čo je uvedené pod "files", "include" a "exclude" v tsconfig.json.
// foo.d.ts
declare module 'foo';
Potom, keď importujete foo, bude to jednoducho typované ako any.
Alebo, ak chcete vytvoriť vlastné typy, môžete to urobiť tiež:
// foo.d.ts
declare module 'foo' {
export function getRandomNumber(): number
}
Potom sa toto skompiluje správne:
import { getRandomNumber } from 'foo';
const x = getRandomNumber(); // x is inferred as number
Nemusíte poskytovať úplné typovanie pre modul, stačí to, čo je potrebné pre časti, ktoré skutočne používate (a chcete pre ne správne typovanie), takže je to obzvlášť jednoduché, ak používate pomerne malé množstvo API.
Na druhej strane, ak sa nestaráte o typy externých knižníc a chcete, aby všetky knižnice bez typov boli importované ako any, môžete to pridať do súboru s príponou .d.ts:
declare module '*';
Výhodou (a nevýhodou) toho je, že môžete importovať prakticky čokoľvek a TypeScript to skompiluje.
Odpoveď č. 3
Ak potrebujete rýchle riešenie, jednoducho pridajte toto pred riadok vášho importu:
// @ts-ignore
Odpoveď č. 4
Pre situáciu, keď inštalujete svoj vlastný balík npm
Ak používate balík tretej strany, pozrite si moju odpoveď nižšie.
Odstráňte .js z "main": "dist/index.js" v package.json.
"main": "dist/index",
Tiež pridajte types do package.json podľa dokumentácie TypeScriptu:
"main": "dist/index",
"types": "dist/index",
Priečinok dist je miesto, kde TS kompilátor ukladá súbory vášho modulu.
Odpoveď č. 5
Pre kohokoľvek iného, kto toto číta, skúste premenovať svoj súbor .js na .ts
Upraviť: Do súboru tsconfig môžete tiež pridať "allowJs": false.
Odpoveď č. 6
TypeScript v podstate implementuje pravidlá a pridáva typy do vášho kódu, aby bol jasnejší a presnejší vzhľadom na nedostatok obmedzení v JavaScripte. TypeScript vyžaduje, aby ste opísali svoje dáta, aby kompilátor mohol skontrolovať váš kód a nájsť chyby. Kompilátor vás upozorní, ak používate nezodpovedajúce typy, ak ste mimo svojho rozsahu alebo ak sa pokúšate vrátiť iný typ. Takže keď používate externé knižnice a moduly s TypeScriptom, musia obsahovať súbory, ktoré opisujú typy v tom kóde. Tieto súbory sa nazývajú súbory deklarácie typov s príponou d.ts. Väčšina typov deklarácií pre npm moduly je už napísaná a môžete ich zahrnúť pomocou npm install @types/nazov_modulu (kde nazov_modulu je názov modulu, ktorého typy chcete zahrnúť).
Existujú však moduly, ktoré nemajú svoje definície typov, a aby sa chyba odstránila a modul sa importoval pomocou import * as module_name from 'module-name', vytvorte v koreňovom adresári vášho projektu priečinok typings, vo vnútri vytvorte nový priečinok s názvom vášho modulu a v tom priečinku vytvorte súbor module_name.d.ts a napíšte declare module 'module_name'. Potom jednoducho prejdite do súboru tsconfig.json a pridajte "typeRoots": [ " ./../typings", "../../node_modules/@types"] v compilerOptions (s správnou relatívnou cestou k vašim priečinkom), aby TypeScript vedel, kde môže nájsť definície typov vašich knižníc a modulov, a pridajte novú vlastnosť "exclude": ["../../node_modules", "../../typings"] do súboru. Tu je príklad, ako by mal vyzerať váš súbor tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": true,
"sourceMap": true,
"outDir": "../dst/",
"target": "ESNEXT",
"typeRoots": [
"../../typings",
"../../node_modules/@types"
]
},
"lib": [
"es2016"
],
"exclude": [
"../../node_modules",
"../../typings"
]
}
Týmto spôsobom sa chyba odstráni a budete môcť dodržiavať najnovšie pravidlá ES6 a TypeScriptu.
Odpoveď č. 7
Týmto spôsobom to pre mňa funguje:
1. pridajte vlastné deklarácie v deklaračnom súbore, napríklad index.d.ts (možno pod koreňom projektu)
declare module 'Injector';
2. pridajte svoj index.d.ts do tsconfig.json
{
"compilerOptions": {
"strictNullChecks": true,
"moduleResolution": "node",
"jsx": "react",
"noUnusedParameters": true,
"noUnusedLocals": true,
"allowSyntheticDefaultImports":true,
"target": "es5",
"module": "ES2015",
"declaration": true,
"outDir": "./lib",
"noImplicitAny": true,
"importHelpers": true
},
"include": [
"src/**/*",
"index.d.ts", // declaration file path
],
"compileOnSave": false
}
Odpoveď č. 8
Bohužiaľ, nie je v našich rukách rozhodnúť, či si tvorca balíka dá záležať na deklaráčnom súbore. Čo obvykle robím, je mať súbor, ako je index.d.ts, ktorý bude obsahovať všetky chýbajúce deklarácie zo rôznych balíkov:
Index.d.ts:
declare module 'v-tooltip';
declare module 'parse5';
declare module 'emoji-mart-vue-fast';
a odkázať na to vo vašom tsconfig.js:
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx",
"index.d.ts" // this
]
Odpoveď č. 9
Stačí vytvoriť súbor s názvom typings.d.ts v koreňovom adresári vášho projektu. Do tohto súboru len pridajte declare module <module_name>. Tu môže byť module_name názov ľubovoľného modulu, ktorý chcete importovať. Nakoniec otvorte súbor tsconfig.json a zahrňte súbor typings.d.ts do poľa s názvom include array.
// typings.d.ts
declare module 'abc-module';
// tsconfig.json
{
...
"include": [
"src", "typings.d.ts"
]
}
// BOOM, Problem solved!!!
Táto technika poskytuje vášmu modulu typ s názvom „any“. Pre viac informácií: https://medium.com/@steveruiz/using-a-javascript-library-without-type-declarations-in-a-typescript-project-3643490015f3
Odpoveď č. 10
Toto mi fungovalo.
// modules.d.ts
declare module 'my-module';
// tsconfig.json
{
...
"include": [
...
"src", "modules.d.ts"
]
}
// Import
import * as MyModule from 'my-module'
...
const theModule = MyModule()
...
Odpoveď č. 11
Toto je spôsob, akým som to dal do poriadku.
V mojom prípade som použil knižnicu, ktorá nemá definované typy: react-mobile-datepicker
a. Vytvorte priečinok vo vnútri /src. V mojom prípade som použil túto cestu: /src/typings/.
b. Vytvorte súbor .d.ts. Pre môj príklad: /src/typings/react-mobile-datepicker.d.ts
c. Použil som nasledujúci kód na rozšírenie jeho vlastností a zabezpečenie typovej bezpečnosti:
declare module 'react-mobile-datepicker' {
class DatePicker extends React.Component<DatePickerProps, any> {}
interface DatePickerProps {
isPopup?: boolean;
theme?: string;
dateConfig?: DatePickerConfig;
}
export interface DatePickerConfig {
prop1: number;
pro2: string;
}
export default DatePicker;
}
d. Importujte svoje typy tak, ako by ste to normálne robili tam, kde používate knižnicu tretích strán.
import DatePicker, { DatePickerConfig, DatePickerConfigDate } from 'react-mobile-datepicker';
e. Zmeňte tsconfig.json a pridajte tento kód:
{
"compilerOptions": {
//...other properties
"typeRoots": [
"src/typings",
"node_modules/@types"
]
}}
Odkazy na články, ktoré som použil ako zdroj:
https://templecoding.com/blog/2016/03/31/creating-typescript-typings-for-existing-react-components
https://www.credera.com/insights/typescript-adding-custom-type-definitions-for-existing-libraries
