create index.d.ts for read-more-react npm package - javascript

I have a typescript project,
I am trying to import read-more-react but beacuse it doesn't have a #type defined for it, I need to write the index.d.ts file myself (place it under #type/read-more-react),
I have tried this:
declare module 'read-more-react' {
import React from 'react';
declare const ReadMoreReact: React.FunctionComponent<ReadMoreReactProps>;
}
interface ReadMoreReactProps {
text: string
min: number
ideal: number
max: number
readMoreText: string
}
but it doesn't seems to work,
can anyone help me in how to successfully implement the index.d.ts file, what am I missing ?

Inside your tsconfig.json file, you need to include your index.d.ts file.
You can do so by adding the following:
{
"include": [
"path/to/your/index.d.ts",
]
}
Also use this code instead:
declare module 'read-more-react' {
import React from 'react';
interface ReadMoreReactProps {
text: string
min: number
ideal: number
max: number
readMoreText: string
}
const ReadMoreReact: React.FC<ReadMoreReactProps>;
export default ReadMoreReact;
}

Related

How to declare types for javascript submodules from npm?

I have JS/TS code base in my project. Some file looks like:
import Something from '#some-lib/things/something'; // index.jsx file here
const someFunction = () => {
// do something with "Something"
};
In VS Code and tsc result i have error:
Could not find a declaration file for module
'#some-lib/things/something'.
'/Users/user/Projects/project/node_modules/#some-lib/things/something/index.jsx'
implicitly has an 'any' type.
Try npm install ... if it exists or add a new declaration (.d.ts)
file containing declare module '#some-lib/things/something';
I tried to add definitions by creatig file src/#types/#some-lib/index.d.ts with this content:
declare module '#some-lib/things/something' {
const Something: (props: React.SVGProps<SVGSVGElement> & {
size?: number,
color?: string,
inline?: boolean,
className?: string,
}) => React.ReactElement;
export default Icon;
}
But i get this error:
Invalid module name in augmentation.
Module '#some-lib/things/something' resolves to an untyped module at '/Users/user/Projects/project/node_modules/#some-lib/things/something/index.jsx', which cannot be augmented.
Please, help me. How can i declare TypeScript types for JS libraries from npm with subdirectories/submodules ?
I found solution.
If you want to create d.ts for js/jsx files from npm-modules you import like this:
// this is reference to ./node_modules/#some-lib/things/something/index.js
import Something from '#some-lib/things/something'
you need to
Add paths to your tsconfig.json:
{
"compilerOptios": {
// ...
"baseUrl": ".", // just require for "paths"
"paths": {
"#some-lib/*": ["src/types/some-lib"] // 'src/types' is just for example
}
}
}
Create file src/types/#some-lib/things/something.d.ts with content:
declare module '#some-lib/things/something' { // equal to import
const Something = number; // number just for example
export = Something;
}
As far as I understand, your d.ts file path in should be the same as the path from node_modules, except that its root starts at src/types/ in example.
I really hope this will help you, good luck!
Duplicate of
Having error "Module 'name' resolves to an untyped module at..." when writing custom TypeScript definition file
Imports should be declared inside the module declaration.

Adding custom Typescript type declaration for a node module in Create React App

I am struggling to add a type declaration for react-load-script within a Create React App application.
Within the src folder, I created a react-load-script.d.ts file and added the following:
// Type definitions for React Load Script
declare module 'react-load-script' {
import * as React from 'react'
interface Script {
url: string
}
}
With the above I am getting the error:
JSX element type 'Script' does not have any construct or call
signatures.
Where am I going wrong? This is the module: https://github.com/blueberryapps/react-load-script
This is my current use of it within the app:
<Script url="https://maps.googleapis.com/maps/api/js? key=your_api_key&libraries=places"
/>
I also need to add types for the onLoad:
<Script url="https://maps.googleapis.com/maps/api/js? key=your_api_key&libraries=places"
onLoad={this.handleScriptLoad}
/>
Thanks so much.
Update from comments
I moved and renamed the declaration file to /#types/react-load-script/index.d.ts
In tsconfig.json I added the following to compilerOptions:
"typeRoots": ["./node_modules/#types", "./#types"]
This is the index.d.ts entire contents:
// Type definitions for React Load Script
import React from 'react'
export interface ScriptProps {
url: string
onLoad: () => void
// etc...
}
export default class Script extends React.Component<ScriptProps> {}
With this I am still getting the error:
Could not find a declaration file for module 'react-load-script'.
'/Users/sb/git/fl-app/node_modules/react-load-script/lib/index.js'
implicitly has an 'any' type.
Note: create a folder called 'custom-types' in the root directory of your project and inside it create the file 'index.d.ts'
index.d.ts
declare module 'your-module-that-has-no-types';
tsconfig.json
{
"compilerOptions": {
// ...other props,
"typeRoots": ["./custom-types", "node_modules/#types"]
},
"include": [
"src"
, "custom-types/index.d.ts" ],
}
It's because Script is the component, but your interface define its props.
Following the lib sources, you may have to do:
export interface ScriptProps {
url: string;
onLoad: () => void;
// etc...
}
export default class Script extends React.Component<ScriptProps> {}
Edit after comments
Your types concerns a third-party module. You have to advise Typescript about it. For that you'll encapsulate your types in a module declaration, like that:
// index.d.ts
declare module 'react-load-script' {
// imports here...
export interface ScriptProps {
url: string;
onLoad: () => void;
// etc...
}
export default class Script extends React.Component<ScriptProps> {}
}

How to properly export/import modules for library usage in javascript

I want to write a javascript library with two files:
snabbpixi.js
export function init() {
}
pixiapi.js
export function createElement() {
}
I want to use this library like this:
import { init } from 'snabbpixi';
import { createElement } from 'snabbpixi/pixiapi';
If I don't do anything and set the package.json for library as:
{
"main": "src/snabbpixi.js"
}
second import doesn't work (import { createElement } from 'snabbpixi/pixiap')
If I compile this library and export as umd format using webpack it also doesn't work.
How can I configure my library so I can import like this:
import { createElement } from 'snabbpixi/pixiap'
I normally do this sort of thing in TypeScript rather than straight JavaScript, but hopefully this works in basically the same way...
Try creating a new file (typically named index.js), with contents like this:
export * from './snabbpixi'; // Adjust paths as needed for your particular case.
export * from './snabbpixi/pixiapi';
Then make index.js your main.
The import you would use would then be flattened-out, however, looking more like:
import { init, createElement } from 'snabbpixi';
When you are using import { Something } from 'somewhere' you are calling on a named export from a given file or directory.
If the two files are in different directories then you can add an index.js file to each directory and then use export { default as function } from './file'
To do this you would have to export the default file from pixiapi and snabbpixi.
If you have both files importing into your index.js then you will still want to export them as defaults. But then you would do the following..
import file1 from './file1'
import file2 from './file2'
export default {
file1,
file2,
}
This will allow you to use the named imports as well and keep them in the same directory

Importing an Interface in Typescript from another file

How do you import an interface from another file?
If I use type I can do the following:
// branch.ts
export type Branch = {
colour: string
}
// tree.ts
import {Branch} from "./branch"
type Tree = {
branch: Branch[]
}
Whereas with interface it complains about it not being a namespace [ts] Cannot use namespace 'Branch' as a type.:
// branch.ts
export interface Branch {
colour: string
}
// tree.ts
import {Branch} from "./branch"
interface Tree {
branch: Branch[]
}
Project structure:
I cant publish the repo sorry, but here is the setup we have. We are using lerna so we are declaring modules in an index.d.ts file e.g. declare module "#shared/branch". It looks like tslint it can't find the interface export properly so complains. The code compiles and runs as expected though

FlowTypes how to import types from private npm module

I am writing private npm package to use internally, I also want to include some flowtypes in there that will be shared between internal projects and imported in following format import type {SomeType} from 'our-private-lib' But I am having trouble in doing so, what is the best approach to include flow types with npm package?
Currently I am transpiling all ES code with babel and then also using flow-copy-source to copy original files over along side transpiled files but with .js.flow extension, but then that means that the name of these files should be the same as the transpiled file?
For example if I have file in /super-schema/index.js with
export type SuperSchemaType = {
prop1: boolean,
prop2: string
}
const SuperSchema = {
prop1: true,
prop2: 'Hello'
}
module.exports = SuperSchema;
And package.json points to main file index.js which exports SuperSchema like so
module.exports = {
superSchema: require('./super-schema.js/index.js');
}
I then can import that like so
import {superSchema} from 'our-private-lib';
but what about flowtype? import type { SuperSchemaType } from 'our-private-lib'; Doesn't really work
Your general approach is correct (using flow-copy-source), but if you want to consume types out of the main entry point of your module, you need to export the types out one way or another. You can do that explicitly by doing something like
export type {
SuperSchemaType
} from './super-schema';
Or, if you're using babel 7, export type * might be useful for you
export type * from './super-schema';

Categories

Resources