reactjs - Korrekt sätt att hantera odefinierade deklarationsfiler (index.d.ts)


Jag fick följande fel

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';`

Som en snabb lösning skapade jag typings/index.d.ts (det finns ingen @types/react-native-camera) fil i roten av mitt projekt och fyllde den med

declare module 'react-native-camera';

sedan, i min tsconfig-fil la jag till det i mina typerötter så här

"typeRoots": ["node_modules/@types", "./typings"],

Jag får dock fortfarande samma fel när jag bygger, vilket får mig att tro att min implementation är felaktig, vad har jag missat?

Redigera, min fullständiga tsconfig ser ut så här

{
  "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"]
}

Svar #1

Alternativet typeRoots anger var man ska leta efter paket som kan innehålla typeinformation. Dokumentationen fortsätter att säga att kompilatorn letar efter paket.

Jag har återskapat strukturen du beskrev och fick samma fel som du. Sedan skapade jag en react-native-camera under typings och flyttade index.d.ts dit så att jag slutade med denna struktur:

typings/
└── react-native-camera
    └── index.d.ts

Med denna struktur fungerar kompileringen helt okej.

Att använda en typings-katalogstruktur är okej, om du vill ha den typen av struktur. För vissa projekt använder jag en typings-katalog. För andra projekt föredrar jag något enklare: en .d.ts-fil i källträdet som deklarerar allt som behöver deklareras. Så om jag utgår från beskrivningen du ger, men tar bort typings och istället lägger till src/definitions.d.ts som innehåller

declare module 'react-native-camera';

då kompileras koden utan problem.

Det är verkligen en fråga om preferens vad man ska använda. Vanligtvis, när ett projekt blir så komplext att src/definitions.d.ts blir svårt att hantera eller svårt att förstå, går jag över till att använda en typings-katalog.

Svar #2

Från flowtype-dokumentet, i avsnittet om biblioteksdefinitioner, stod det:

En libdef är en speciell fil som informerar Flow om typdeklarationen för en viss tredjepartmodul eller paket av moduler som din applikation använder. Om du är bekant med språk som har header-filer (som C++), kan du tänka på libdefs som ett liknande koncept.

Allmänna bästa praxis

Försök att tillhandahålla en libdef för varje tredjepartsbibliotek som ditt projekt använder.

Titta i .flowconfig i rotvägen, du kommer att se att det redan är definierat där.

[libs]
node_modules/react-native/Libraries/react-native/react-native-interface.js
node_modules/react-native/flow
./libdefs.js

Och sedan leta efter libdefs.js i rotvägen, det borde finnas där. Eller skapa det bara själv.

För varje modul, deklarera den som nedan. Ta rxjs som exempel:

declare module 'rxjs' { declare var exports: any; }

Det är det officiella förslagsättet, ingen index.d.ts ändring behövs.

Relaterade artiklar