Skip to content

Commit 6ab881e

Browse files
committed
JS Doc + TypeScript and JS + DTS examples
1 parent da5c53d commit 6ab881e

12 files changed

+322
-2
lines changed

README.md

+104-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,109 @@
11
# ts-guideline
22

3+
<font size="4">
4+
35
Minimalistic configuration for TS to only extend JS with types. No TS-scpecific features, no bundling. Readable maintainable code after compilation.
46

5-
- **commonjs** folder for CommonJS Modules ts-configuration compatible with ECMAScript import
7+
- **commonjs** folder for CommonJS Modules ts-configuration compatible with ECMAScript import
8+
9+
- **ecmascript** folder for ECMAScript Modules ts-configuration
10+
11+
- **js-dts** folder for JS + DTS configuration
12+
13+
- **js-doc** folder for JS Doc + TypeScript configuration
14+
15+
</font>
16+
17+
# Reccomendations
18+
19+
<font size="4">
20+
21+
1. **Avoid** using **type aliases** - example from mongoose types
22+
23+
```ts
24+
export type ApplyBasicQueryCasting<T> = T | T[] | (T extends (infer U)[] ? U : any) | any;
25+
```
26+
27+
this is unreadable and overcomplicated
28+
29+
**Aliases are** good **only** for **simple** types
30+
31+
```ts
32+
type Fruit = 'banana' | 'orange' | 'pineapple' | 'watermelon';
33+
34+
type Debt = { amount: number; dueTo: Date };
35+
type AccountDebt = { accountId: number; debt: Debt | null };
36+
```
37+
38+
2. **Never use complicated generic types** - example from mongoose types
39+
```ts
40+
type QueryWithHelpers<ResultType, DocType, THelpers = {}, RawDocType = DocType> = Query<
41+
ResultType,
42+
DocType,
43+
THelpers,
44+
RawDocType
45+
> &
46+
THelpers;
47+
```
48+
basically is is looks worse then
49+
```ts
50+
type QueryWithHelpers<any> = Query<any> & any;
51+
```
52+
3. Not everything is neccessary to cover with types.
53+
54+
It requires to add useless interfaces for type like this. Better just not use this.
55+
56+
```ts
57+
// with typing
58+
interface IDynamicGeneratedClass {}
59+
60+
const classGenerator = (): IDynamicGeneratedClass =>
61+
class DynamicGeneratedClass implements IDynamicGeneratedClass {
62+
args: number[];
63+
constructor(...args: number[]) {
64+
this.args = args;
65+
}
66+
};
67+
```
68+
69+
```ts
70+
// simplified
71+
const classGenerator = () =>
72+
class DynamicGeneratedClass {
73+
args: number[];
74+
constructor(...args: number[]) {
75+
this.args = args;
76+
}
77+
};
78+
```
79+
80+
4. avoid using `any` - there is no point at all to use typescript if you need to keep using `any`.
81+
82+
This list will continue in future.
83+
84+
</font>
85+
86+
# Alternatives
87+
88+
<font size="4">
89+
90+
1. You can use JS Doc @type for type definitions, typescript will work and check types for you
91+
92+
2. You can always use JS + DTS - it is a similar way as it is done in C++ with .h and .cpp files
93+
DTS files are not working perfectly. Sometimes you forced to use JS Doc @typedef to import types from d.ts files
94+
95+
</font>
96+
97+
# Summary
98+
99+
<font size="4">
100+
101+
I prefer to use JS + DTS or JS DOC + TypeScript, because it solve every type issues, but not requires to write code in TypeScript
102+
103+
If it is not possible for you to follow this 2 solutions, please think about using those TS Guidelines. It will save you a lot of pain in future.
104+
105+
TypeScript will sync their development withing the JavaScript standard. This means there will be no TS Decorators and TypeScript will become more like JS Extension rather than a different language transpiled to JS.
106+
107+
</font>
6108

7-
- **ecmascript** folder for ECMAScript Modules ts-configuration
109+
[![Good talks about Types and JS/TS future](https://img.youtube.com/vi/SdV9Xy0E4CM/0.jpg)](https://www.youtube.com/watch?v=SdV9Xy0E4CM)

js-doc/main.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const { sum, Summator } = require('./src/sum.js');
2+
3+
sum(1, 2);
4+
5+
// Uncomment to receive an error
6+
// sum('s', 's');
7+
8+
const summator = new Summator(1, 2, 3);
9+
10+
summator.summary();

js-doc/package-lock.json

+37
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js-doc/package.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "ts-guideline",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "sum.js",
6+
"type": "commonjs",
7+
"scripts": {
8+
"check": "npx tsc --project .",
9+
"test": "echo \"Error: no test specified\" && exit 1"
10+
},
11+
"keywords": [],
12+
"author": "",
13+
"license": "ISC",
14+
"devDependencies": {
15+
"typescript": "^4.8.2"
16+
}
17+
}

js-doc/src/sum.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/** @type {(a: number, b: number) => number} */
2+
export const sum = (a, b) => a + b;
3+
4+
export class Summator {
5+
/** @arg {number[]} args */
6+
constructor(...args) {
7+
/** @type {number[]} */
8+
this.args = args;
9+
}
10+
/** @type {() => number} */
11+
summary() {
12+
return this.args.reduce((a, b) => a + b, 0);
13+
}
14+
}

js-doc/tsconfig.json

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"compilerOptions": {
3+
"noEmit": true,
4+
"checkJs": true,
5+
"target": "ES2022",
6+
"module": "CommonJS",
7+
"lib": ["ES2022"],
8+
"esModuleInterop": true,
9+
"isolatedModules": true,
10+
"moduleResolution": "node",
11+
12+
"emitDecoratorMetadata": false,
13+
"experimentalDecorators": false,
14+
15+
"strict": true,
16+
"alwaysStrict": true,
17+
"allowUnreachableCode": true,
18+
"allowUnusedLabels": true,
19+
"noImplicitAny": false,
20+
"noImplicitReturns": true,
21+
"resolveJsonModule": true,
22+
23+
"declaration": true
24+
}
25+
}

js-dts/main.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const { sum, Summator } = require('./src/sum.js');
2+
3+
sum(1, 2);
4+
5+
// Uncomment to receive an error
6+
// sum('s', 's');
7+
8+
const summator = new Summator(1, 2, 3);
9+
10+
summator.summary();

js-dts/package-lock.json

+37
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js-dts/package.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "ts-guideline",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "sum.js",
6+
"type": "commonjs",
7+
"scripts": {
8+
"check": "npx tsc --project .",
9+
"test": "echo \"Error: no test specified\" && exit 1"
10+
},
11+
"keywords": [],
12+
"author": "",
13+
"license": "ISC",
14+
"devDependencies": {
15+
"typescript": "^4.8.2"
16+
}
17+
}

js-dts/src/sum.d.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export function sum(a: number, b: number): number;
2+
3+
export class Summator {
4+
args: number[];
5+
constructor(...args: number[]);
6+
summary(): number;
7+
}

js-dts/src/sum.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @typedef {import('./sum').sum} sum;
3+
* @typedef {import('./sum').Summator} ISummator;
4+
*/
5+
6+
/** @type {sum} */
7+
export const sum = (a, b) => a + b;
8+
9+
/** @implements {ISummator} */
10+
export class Summator {
11+
/** @arg {number[]} args */
12+
constructor(...args) {
13+
this.args = args;
14+
}
15+
16+
summary() {
17+
return this.args.reduce((a, b) => a + b, 0);
18+
}
19+
}

js-dts/tsconfig.json

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"compilerOptions": {
3+
"noEmit": true,
4+
"checkJs": true,
5+
"target": "ES2022",
6+
"module": "CommonJS",
7+
"lib": ["ES2022"],
8+
"esModuleInterop": true,
9+
"isolatedModules": true,
10+
"moduleResolution": "node",
11+
12+
"emitDecoratorMetadata": false,
13+
"experimentalDecorators": false,
14+
15+
"strict": true,
16+
"alwaysStrict": true,
17+
"allowUnreachableCode": true,
18+
"allowUnusedLabels": true,
19+
"noImplicitAny": false,
20+
"noImplicitReturns": true,
21+
"resolveJsonModule": true,
22+
23+
"declaration": true
24+
}
25+
}

0 commit comments

Comments
 (0)