Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Commit

Permalink
fix: typedef resolution & add examples that use types (#3359)
Browse files Browse the repository at this point in the history
1. addresses #3356 in a different way based no findings in #3358. 
2. Adds ts project example that uses ipfs and tests that it type checks.
3. Adds js project example that uses ipfs and runs type checker to ensure types are picked up and inferred.
4. Changes all the `ReturnType<import(...)>`'s to `ReturnType<typeof import(...)>` as former seems to raise errors in stricter TS setup.

Co-authored-by: achingbrain <alex@achingbrain.net>
  • Loading branch information
Gozala and achingbrain authored Nov 2, 2020
1 parent b5ea76a commit dc2795a
Show file tree
Hide file tree
Showing 43 changed files with 347 additions and 115 deletions.
56 changes: 56 additions & 0 deletions examples/types-use-ipfs-from-ts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Using IPFS with Typescript

> This example provides a template for using js-ipfs in typescript project.

## Before you start

First clone this repo, install dependencies in the project root.

```
git clone https://github.com/ipfs/js-ipfs.git
cd js-ipfs/examples/types-use-ipfs-from-ts
npm install
```

You can type check this example by runing following in the example directory:

```
npm test
```

You should see following output:

```
> tsc --noEmit
```

If you remove `// @ts-expect-error` comment is `src/main.ts` on line 16 and run `npm test` once again you should see a following output instead:

```
tsc --noEmit
src/main.ts:16:14 - error TS2339: Property 'toUpperCase' does not exist on type 'CID'.
16 file.cid.toUpperCase()
~~~~~~~~~~~
Found 1 error.
```


## IntelliSense

In [VSCode](https://code.visualstudio.com/) and other code editors that provide [comparable IntelliSense features](https://docs.microsoft.com/en-us/visualstudio/ide/using-intellisense?view=vs-2019) you should be able to get code auto complete, parameter and return value information for `js-ipfs` APIs.

![Preview](./preview.png)

## Limitations

- Things should work out of the box, with most `tsconfig` settings, however unless
[`skipLibCheck`](https://www.typescriptlang.org/tsconfig#skipLibCheck) is set to `true` many errors will be reported.
> That is because
types are generated from source JSDoc comments and typescript seems to emit declarations which it then complains about.

- Not all APIs are fully entyped so you might observe gaps and `any` types here and there. We hope to improve this over time.
13 changes: 13 additions & 0 deletions examples/types-use-ipfs-from-ts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "types-use-ipfs-from-ts",
"private": true,
"dependencies": {
"ipfs": "^0.51.0"
},
"devDependencies": {
"typescript": "^4.0.3"
},
"scripts": {
"test": "tsc --noEmit"
}
}
Binary file added examples/types-use-ipfs-from-ts/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions examples/types-use-ipfs-from-ts/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import IPFS from 'ipfs'

export default async function main () {
const node = await IPFS.create()
const version = await node.version()

console.log('Version:', version.version)

const file = await node.add({
path: 'hello.txt',
content: new TextEncoder().encode('Hello World 101')
})

console.log('Added file:', file.path, file.cid.toString())
try {
file.cid.toUpperCase()
} catch(error) {

}

const decoder = new TextDecoder()
let content = ''
for await (const chunk of node.cat(file.cid)) {
content += decoder.decode(chunk)
}

console.log('Added file contents:', content)
}
13 changes: 13 additions & 0 deletions examples/types-use-ipfs-from-ts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"strict": true,
"skipLibCheck": true,
"noImplicitAny": false,
"esModuleInterop": true,
"moduleResolution": "Node",
"noEmit": true
},
"include": [
"src"
]
}
59 changes: 59 additions & 0 deletions examples/types-use-ipfs-from-typed-js/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Using IPFS with typed JS

> This example provides a template for setting up a [JS project that utilizes type checker](https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html) and `js-ipfs` type [declarations the were generated from JSDoc comments](https://www.typescriptlang.org/docs/handbook/declaration-files/dts-from-js.html)
Things should work out of the box, only requirement is to disable
[`skipLibCheck`](https://www.typescriptlang.org/tsconfig#skipLibCheck) because type declarations generated by typescript for commonjs modules raise some issues when consumed.


## Before you start

First clone this repo, install dependencies in the project root.

```
git clone https://github.com/ipfs/js-ipfs.git
cd js-ipfs/examples/types-use-ipfs-from-typed-js
npm install
```

## Type checking

You can type check this example by runing following in the example directory:

```
npm test
```

You should see following output:

```
> tsc --noEmit
```

If you remove `// @ts-expect-error` comment is `src/main.js` on line 16 and run `npm test` once again you should see a following output instead:

```
> tsc --noEmit
src/main.js:16:14 - error TS2339: Property 'toUpperCase' does not exist on type 'CID'.
16 file.cid.toUpperCase()
~~~~~~~~~~~
Found 1 error.
```

## IntelliSense

In [VSCode](https://code.visualstudio.com/) and other code editors that provide [comparable IntelliSense features](https://docs.microsoft.com/en-us/visualstudio/ide/using-intellisense?view=vs-2019) you should be able to get code auto complete, parameter and return value information for `js-ipfs` APIs.

![Preview](./preview.png)

## Limitations

- Things should work out of the box, with most `tsconfig` settings, however unless
[`skipLibCheck`](https://www.typescriptlang.org/tsconfig#skipLibCheck) is set to `true` many errors will be reported.
> That is because
types are generated from source JSDoc comments and typescript seems to emit declarations which it then complains about.

- Not all APIs are fully entyped so you might observe gaps and `any` types here and there. We hope to improve this over time.
13 changes: 13 additions & 0 deletions examples/types-use-ipfs-from-typed-js/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "types-use-ipfs-from-typed-js",
"private": true,
"dependencies": {
"ipfs": "^0.51.0"
},
"devDependencies": {
"typescript": "^4.0.3"
},
"scripts": {
"test": "tsc --noEmit"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions examples/types-use-ipfs-from-typed-js/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const IPFS = require('ipfs')

async function main () {
const node = await IPFS.create()
const version = await node.version()

console.log('Version:', version.version)

const file = await node.add({
path: 'hello.txt',
content: new TextEncoder().encode('Hello World 101')
})

console.log('Added file:', file.path, file.cid.toString())
try {
file.cid.toUpperCase()
} catch(error) {

}

const decoder = new TextDecoder()
let content = ''
for await (const chunk of node.cat(file.cid)) {
content += decoder.decode(chunk)
}

console.log('Added file contents:', content)
}

main()
15 changes: 15 additions & 0 deletions examples/types-use-ipfs-from-typed-js/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"strict": true,
"skipLibCheck": true,
"noImplicitAny": false,
"esModuleInterop": true,
"moduleResolution": "Node",
"noEmit": true
},
"include": [
"src"
]
}
3 changes: 2 additions & 1 deletion packages/ipfs-core-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"typesVersions": {
"*": {
"*": [
"dist/*"
"dist/*",
"dist/*/index"
]
}
},
Expand Down
3 changes: 2 additions & 1 deletion packages/ipfs-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"typesVersions": {
"*": {
"*": [
"dist/*"
"dist/*",
"dist/*/index"
]
}
},
Expand Down
22 changes: 11 additions & 11 deletions packages/ipfs-core/src/components/files/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ const isIpfs = require('is-ipfs')

/**
* @typedef {Object} MFS
* @property {ReturnType<import('./stat')>} stat
* @property {ReturnType<import('./chmod')>} chmod
* @property {ReturnType<import('./cp')>} cp
* @property {ReturnType<import('./flush')>} flush
* @property {ReturnType<import('./mkdir')>} mkdir
* @property {ReturnType<import('./mv')>} mv
* @property {ReturnType<import('./rm')>} rm
* @property {ReturnType<import('./touch')>} touch
* @property {ReturnType<import('./write')>} write
* @property {ReturnType<import('./read')>} read
* @property {ReturnType<import('./ls')>} ls
* @property {ReturnType<typeof import('./stat')>} stat
* @property {ReturnType<typeof import('./chmod')>} chmod
* @property {ReturnType<typeof import('./cp')>} cp
* @property {ReturnType<typeof import('./flush')>} flush
* @property {ReturnType<typeof import('./mkdir')>} mkdir
* @property {ReturnType<typeof import('./mv')>} mv
* @property {ReturnType<typeof import('./rm')>} rm
* @property {ReturnType<typeof import('./touch')>} touch
* @property {ReturnType<typeof import('./write')>} write
* @property {ReturnType<typeof import('./read')>} read
* @property {ReturnType<typeof import('./ls')>} ls
*/

// These operations are read-locked at the function level and will execute simultaneously
Expand Down
Loading

0 comments on commit dc2795a

Please sign in to comment.